// SaltarelleCompiler Runtime (http://www.saltarelle-compiler.com)
// Modified version of Script# Core Runtime (http://projects.nikhilk.net/ScriptSharp)

if (typeof (global) === "undefined") {
    if (typeof (window) !== "undefined")
        global = window;
    else if (typeof (self) !== "undefined")
        global = self;
}
(function (global) {
    "use strict";

    var ss = { __assemblies: {} };

    ss.initAssembly = function assembly(obj, name, res) {
        res = res || {};
        obj.name = name;
        obj.toString = function () { return this.name; };
        obj.__types = {};
        obj.getResourceNames = function () { return Object.keys(res); };
        obj.getResourceDataBase64 = function (name) { return res[name] || null; };
        obj.getResourceData = function (name) { var r = res[name]; return r ? ss.dec64(r) : null; };
        ss.__assemblies[name] = obj;
    };
    ss.initAssembly(ss, 'mscorlib');

    ss.load = function ss$load(name) {
        return ss.__assemblies[name] || require(name);
    };

    var enc = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/', dec;
    ss.enc64 = function (a, b) {
        var s = '', i;
        for (i = 0; i < a.length; i += 3) {
            var c1 = a[i], c2 = a[i + 1], c3 = a[i + 2];
            s += (b && i && !(i % 57) ? '\n' : '') + enc[c1 >> 2] + enc[((c1 & 3) << 4) | (c2 >> 4)] + (i < a.length - 1 ? enc[((c2 & 15) << 2) | (c3 >> 6)] : '=') + (i < a.length - 2 ? enc[c3 & 63] : '=');
        }
        return s;
    };

    ss.dec64 = function (s) {
        s = s.replace(/\s/g, '');
        dec = dec || (function () { var o = { '=': -1 }; for (var i = 0; i < 64; i++) o[enc[i]] = i; return o; })();
        var a = Array(Math.max(s.length * 3 / 4 - 2, 0)), i;
        for (i = 0; i < s.length; i += 4) {
            var j = i * 3 / 4, c1 = dec[s[i]], c2 = dec[s[i + 1]], c3 = dec[s[i + 2]], c4 = dec[s[i + 3]];
            a[j] = (c1 << 2) | (c2 >> 4);
            if (c3 >= 0) a[j + 1] = ((c2 & 15) << 4) | (c3 >> 2);
            if (c4 >= 0) a[j + 2] = ((c3 & 3) << 6) | c4;
        }
        return a;
    };

    ss.getAssemblies = function ss$getAssemblies() {
        return Object.keys(ss.__assemblies).map(function (n) { return ss.__assemblies[n]; });
    };

    ss.isNullOrUndefined = function ss$isNullOrUndefined(o) {
        return (o === null) || (o === undefined);
    };

    ss.isValue = function ss$isValue(o) {
        return (o !== null) && (o !== undefined);
    };

    ss.referenceEquals = function ss$referenceEquals(a, b) {
        return ss.isValue(a) ? a === b : !ss.isValue(b);
    };

    ss.mkdict = function ss$mkdict() {
        var a = (arguments.length != 1 ? arguments : arguments[0]);
        var r = {};
        for (var i = 0; i < a.length; i += 2) {
            r[a[i]] = a[i + 1];
        }
        return r;
    };

    ss.coalesce = function ss$coalesce(a, b) {
        return ss.isValue(a) ? a : b;
    };

    ss.isDate = function ss$isDate(obj) {
        return Object.prototype.toString.call(obj) === '[object Date]';
    };

    ss.isArray = function ss$isArray(obj) {
        return Object.prototype.toString.call(obj) === '[object Array]';
    };

    ss.isTypedArrayType = function ss$isTypedArrayType(type) {
        return ['Float32Array', 'Float64Array', 'Int8Array', 'Int16Array', 'Int32Array', 'Uint8Array', 'Uint16Array', 'Uint32Array', 'Uint8ClampedArray'].indexOf(ss.getTypeFullName(type)) >= 0;
    };

    ss.isArrayOrTypedArray = function ss$isArray(obj) {
        return ss.isArray(obj) || ss.isTypedArrayType(ss.getInstanceType(obj));
    };

    ss.getHashCode = function ss$getHashCode(obj) {
        if (!ss.isValue(obj))
            throw new ss_NullReferenceException('Cannot get hash code of null');
        else if (typeof (obj.getHashCode) === 'function')
            return obj.getHashCode();
        else if (typeof (obj) === 'boolean') {
            return obj ? 1 : 0;
        }
        else if (typeof (obj) === 'number') {
            var s = obj.toExponential();
            s = s.substr(0, s.indexOf('e'));
            return parseInt(s.replace('.', ''), 10) & 0xffffffff;
        }
        else if (typeof (obj) === 'string') {
            var res = 0;
            for (var i = 0; i < obj.length; i++)
                res = (res * 31 + obj.charCodeAt(i)) & 0xffffffff;
            return res;
        }
        else if (ss.isDate(obj)) {
            return obj.valueOf() & 0xffffffff;
        }
        else {
            return ss.defaultHashCode(obj);
        }
    };

    ss.defaultHashCode = function ss$defaultHashCode(obj) {
        return obj.$__hashCode__ || (obj.$__hashCode__ = (Math.random() * 0x100000000) | 0);
    };

    ss.equals = function ss$equals(a, b) {
        if (!ss.isValue(a))
            throw new ss_NullReferenceException('Object is null');
        else if (a !== ss && typeof (a.equals) === 'function')
            return a.equals(b);
        if (ss.isDate(a) && ss.isDate(b))
            return a.valueOf() === b.valueOf();
        else if (typeof (a) === 'function' && typeof (b) === 'function')
            return ss.delegateEquals(a, b);
        else if (ss.isNullOrUndefined(a) && ss.isNullOrUndefined(b))
            return true;
        else
            return a === b;
    };

    ss.compare = function ss$compare(a, b) {
        if (!ss.isValue(a))
            throw new ss_NullReferenceException('Object is null');
        else if (typeof (a) === 'number' || typeof (a) === 'string' || typeof (a) === 'boolean')
            return a < b ? -1 : (a > b ? 1 : 0);
        else if (ss.isDate(a))
            return ss.compare(a.valueOf(), b.valueOf());
        else
            return a.compareTo(b);
    };

    ss.equalsT = function ss$equalsT(a, b) {
        if (!ss.isValue(a))
            throw new ss_NullReferenceException('Object is null');
        else if (typeof (a) === 'number' || typeof (a) === 'string' || typeof (a) === 'boolean')
            return a === b;
        else if (ss.isDate(a))
            return a.valueOf() === b.valueOf();
        else
            return a.equalsT(b);
    };

    ss.staticEquals = function ss$staticEquals(a, b) {
        if (!ss.isValue(a))
            return !ss.isValue(b);
        else
            return ss.isValue(b) ? ss.equals(a, b) : false;
    };

    ss.shallowCopy = function ss$shallowCopy(source, target) {
        var keys = Object.keys(source);
        for (var i = 0, l = keys.length; i < l; i++) {
            var k = keys[i];
            target[k] = source[k];
        }
    };

    ss.isLower = function ss$isLower(c) {
        var s = String.fromCharCode(c);
        return s === s.toLowerCase() && s !== s.toUpperCase();
    };

    ss.isUpper = function ss$isUpper(c) {
        var s = String.fromCharCode(c);
        return s !== s.toLowerCase() && s === s.toUpperCase();
    };

    if (typeof (window) == 'object') {
        // Browser-specific stuff that could go into the Web assembly, but that assembly does not have an associated JS file.
        if (!window.Element) {
            // IE does not have an Element constructor. This implementation should make casting to elements work.
            window.Element = function () { };
            window.Element.isInstanceOfType = function (instance) { return instance && typeof instance.constructor === 'undefined' && typeof instance.tagName === 'string'; };
        }
        window.Element.__typeName = 'Element';

        if (!window.XMLHttpRequest) {
            window.XMLHttpRequest = function () {
                var progIDs = ['Msxml2.XMLHTTP', 'Microsoft.XMLHTTP'];

                for (var i = 0; i < progIDs.length; i++) {
                    try {
                        var xmlHttp = new ActiveXObject(progIDs[i]);
                        return xmlHttp;
                    }
                    catch (ex) {
                    }
                }

                return null;
            };
        }

        ss.parseXml = function (markup) {
            try {
                if (DOMParser) {
                    var domParser = new DOMParser();
                    return domParser.parseFromString(markup, 'text/xml');
                }
                else {
                    var progIDs = ['Msxml2.DOMDocument.3.0', 'Msxml2.DOMDocument'];

                    for (var i = 0; i < progIDs.length; i++) {
                        var xmlDOM = new ActiveXObject(progIDs[i]);
                        xmlDOM.async = false;
                        xmlDOM.loadXML(markup);
                        xmlDOM.setProperty('SelectionLanguage', 'XPath');
                        return xmlDOM;
                    }
                }
            }
            catch (ex) {
            }

            return null;
        };
    }

    ///////////////////////////////////////////////////////////////////////////////
    // Object Extensions

    ss.clearKeys = function ss$clearKeys(d) {
        for (var n in d) {
            if (d.hasOwnProperty(n))
                delete d[n];
        }
    };

    ss.keyExists = function ss$keyExists(d, key) {
        return d[key] !== undefined;
    };

    if (!Object.keys) {
        Object.keys = (function () {
            'use strict';
            var hasOwnProperty = Object.prototype.hasOwnProperty,
                hasDontEnumBug = !({ toString: null }).propertyIsEnumerable('toString'),
                dontEnums = ['toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor'],
                dontEnumsLength = dontEnums.length;

            return function (obj) {
                if (typeof obj !== 'object' && (typeof obj !== 'function' || obj === null)) {
                    throw new TypeError('Object.keys called on non-object');
                }

                var result = [], prop, i;

                for (prop in obj) {
                    if (hasOwnProperty.call(obj, prop)) {
                        result.push(prop);
                    }
                }

                if (hasDontEnumBug) {
                    for (i = 0; i < dontEnumsLength; i++) {
                        if (hasOwnProperty.call(obj, dontEnums[i])) {
                            result.push(dontEnums[i]);
                        }
                    }
                }
                return result;
            };
        }());
    }

    ss.getKeyCount = function ss$getKeyCount(d) {
        return Object.keys(d).length;
    };

    ///////////////////////////////////////////////////////////////////////////////
    // Type System Implementation

    ss.__genericCache = {};

    ss._makeGenericTypeName = function ss$_makeGenericTypeName(genericType, typeArguments) {
        var result = genericType.__typeName;
        for (var i = 0; i < typeArguments.length; i++)
            result += (i === 0 ? '[' : ',') + '[' + ss.getTypeQName(typeArguments[i]) + ']';
        result += ']';
        return result;
    };

    ss.makeGenericType = function ss$makeGenericType(genericType, typeArguments) {
        var name = ss._makeGenericTypeName(genericType, typeArguments);
        return ss.__genericCache[name] || genericType.apply(null, typeArguments);
    };

    ss.registerGenericClassInstance = function ss$registerGenericClassInstance(instance, genericType, typeArguments, members, baseType, interfaceTypes) {
        var name = ss._makeGenericTypeName(genericType, typeArguments);
        ss.__genericCache[name] = instance;
        instance.__typeName = name;
        instance.__genericTypeDefinition = genericType;
        instance.__typeArguments = typeArguments;
        ss.initClass(instance, genericType.__assembly, members, baseType(), interfaceTypes());
    };

    ss.registerGenericInterfaceInstance = function ss$registerGenericInterfaceInstance(instance, genericType, typeArguments, members, baseInterfaces) {
        var name = ss._makeGenericTypeName(genericType, typeArguments);
        ss.__genericCache[name] = instance;
        instance.__typeName = name;
        instance.__genericTypeDefinition = genericType;
        instance.__typeArguments = typeArguments;
        ss.initInterface(instance, genericType.__assembly, members, baseInterfaces());
    };

    ss.isGenericTypeDefinition = function ss$isGenericTypeDefinition(type) {
        return type.__isGenericTypeDefinition || false;
    };

    ss.getGenericTypeDefinition = function ss$getGenericTypeDefinition(type) {
        return type.__genericTypeDefinition || null;
    };

    ss.getGenericParameterCount = function ss$getGenericParameterCount(type) {
        return type.__typeArgumentCount || 0;
    };

    ss.getGenericArguments = function ss$getGenericArguments(type) {
        return type.__typeArguments || null;
    };

    ss.setMetadata = function ss$_setMetadata(type, metadata) {
        if (metadata.members) {
            for (var i = 0; i < metadata.members.length; i++) {
                var m = metadata.members[i];
                m.typeDef = type;
                if (m.adder) m.adder.typeDef = type;
                if (m.remover) m.remover.typeDef = type;
                if (m.getter) m.getter.typeDef = type;
                if (m.setter) m.setter.typeDef = type;
            }
        }
        type.__metadata = metadata;
        if (metadata.variance) {
            type.isAssignableFrom = function (source) {
                var check = function (target, type) {
                    if (type.__genericTypeDefinition === target.__genericTypeDefinition && type.__typeArguments.length == target.__typeArguments.length) {
                        for (var i = 0; i < target.__typeArguments.length; i++) {
                            var v = target.__metadata.variance[i], t = target.__typeArguments[i], s = type.__typeArguments[i];
                            switch (v) {
                                case 1: if (!ss.isAssignableFrom(t, s)) return false; break;
                                case 2: if (!ss.isAssignableFrom(s, t)) return false; break;
                                default: if (s !== t) return false;
                            }
                        }
                        return true;
                    }
                    return false;
                };

                if (source.__interface && check(this, source))
                    return true;
                var ifs = ss.getInterfaces(source);
                for (var i = 0; i < ifs.length; i++) {
                    if (ifs[i] === this || check(this, ifs[i]))
                        return true;
                }
                return false;
            };
        }
    }

    ss.initClass = function ss$initClass(ctor, asm, members, baseType, interfaces) {
        ctor.__class = true;
        ctor.__assembly = asm;
        if (!ctor.__typeArguments)
            asm.__types[ctor.__typeName] = ctor;
        if (baseType && baseType !== Object) {
            var f = function () { };
            f.prototype = baseType.prototype;
            ctor.prototype = new f();
            ctor.prototype.constructor = ctor;
        }
        ss.shallowCopy(members, ctor.prototype);
        if (interfaces)
            ctor.__interfaces = interfaces;
    };

    ss.initGenericClass = function ss$initGenericClass(ctor, asm, typeArgumentCount) {
        ctor.__class = true;
        ctor.__assembly = asm;
        asm.__types[ctor.__typeName] = ctor;
        ctor.__typeArgumentCount = typeArgumentCount;
        ctor.__isGenericTypeDefinition = true;
    };

    ss.initInterface = function ss$initInterface(ctor, asm, members, baseInterfaces) {
        ctor.__interface = true;
        ctor.__assembly = asm;
        if (!ctor.__typeArguments)
            asm.__types[ctor.__typeName] = ctor;
        if (baseInterfaces)
            ctor.__interfaces = baseInterfaces;
        ss.shallowCopy(members, ctor.prototype);
        ctor.isAssignableFrom = function (type) { return ss.contains(ss.getInterfaces(type), this); };
    };

    ss.initGenericInterface = function ss$initGenericClass(ctor, asm, typeArgumentCount) {
        ctor.__interface = true;
        ctor.__assembly = asm;
        asm.__types[ctor.__typeName] = ctor;
        ctor.__typeArgumentCount = typeArgumentCount;
        ctor.__isGenericTypeDefinition = true;
    };

    ss.initEnum = function ss$initEnum(ctor, asm, members, namedValues) {
        ctor.__enum = true;
        ctor.__assembly = asm;
        asm.__types[ctor.__typeName] = ctor;
        ss.shallowCopy(members, ctor.prototype);
        ctor.getDefaultValue = ctor.createInstance = function () { return namedValues ? null : 0; };
        ctor.isInstanceOfType = function (instance) { return typeof (instance) == (namedValues ? 'string' : 'number'); };
    };

    ss.getBaseType = function ss$getBaseType(type) {
        if (type === Object || type.__interface) {
            return null;
        }
        else if (Object.getPrototypeOf) {
            return Object.getPrototypeOf(type.prototype).constructor;
        }
        else {
            var p = type.prototype;
            if (Object.prototype.hasOwnProperty.call(p, 'constructor')) {
                try {
                    var ownValue = p.constructor;
                    delete p.constructor;
                    return p.constructor;
                }
                finally {
                    p.constructor = ownValue;
                }
            }
            return p.constructor;
        }
    };

    ss.getTypeFullName = function ss$getTypeFullName(type) {
        return type.__typeName || type.name || (type.toString().match(/^\s*function\s*([^\s(]+)/) || [])[1] || 'Object';
    };

    ss.getTypeQName = function ss$getTypeFullName(type) {
        return ss.getTypeFullName(type) + (type.__assembly ? ', ' + type.__assembly.name : '');
    };

    ss.getTypeName = function ss$getTypeName(type) {
        var fullName = ss.getTypeFullName(type);
        var bIndex = fullName.indexOf('[');
        var nsIndex = fullName.lastIndexOf('.', bIndex >= 0 ? bIndex : fullName.length);
        return nsIndex > 0 ? fullName.substr(nsIndex + 1) : fullName;
    };

    ss.getTypeNamespace = function ss$getTypeNamespace(type) {
        var fullName = ss.getTypeFullName(type);
        var bIndex = fullName.indexOf('[');
        var nsIndex = fullName.lastIndexOf('.', bIndex >= 0 ? bIndex : fullName.length);
        return nsIndex > 0 ? fullName.substr(0, nsIndex) : '';
    };

    ss.getTypeAssembly = function ss$getTypeAssembly(type) {
        if (ss.contains([Date, Number, Boolean, String, Function, Array], type))
            return ss;
        else
            return type.__assembly || null;
    };

    ss.getAssemblyType = function ss$getAssemblyTypes(asm, name) {
        var result = [];
        if (asm.__types) {
            return asm.__types[name] || null;
        }
        else {
            var a = name.split('.');
            for (var i = 0; i < a.length; i++) {
                asm = asm[a[i]];
                if (!ss.isValue(asm))
                    return null;
            }
            if (typeof asm !== 'function')
                return null;
            return asm;
        }
    };

    ss.getAssemblyTypes = function ss$getAssemblyTypes(asm) {
        var result = [];
        if (asm.__types) {
            for (var t in asm.__types) {
                if (asm.__types.hasOwnProperty(t))
                    result.push(asm.__types[t]);
            }
        }
        else {
            var traverse = function (s, n) {
                for (var c in s) {
                    if (s.hasOwnProperty(c))
                        traverse(s[c], c);
                }
                if (typeof (s) === 'function' && ss.isUpper(n.charCodeAt(0)))
                    result.push(s);
            };
            traverse(asm, '');
        }
        return result;
    };

    ss.createAssemblyInstance = function ss$createAssemblyInstance(asm, typeName) {
        var t = ss.getAssemblyType(asm, typeName);
        return t ? ss.createInstance(t) : null;
    };

    ss.getInterfaces = function ss$getInterfaces(type) {
        if (type.__interfaces)
            return type.__interfaces;
        else if (type === Date || type === Number)
            return [ss_IEquatable, ss_IComparable, ss_IFormattable];
        else if (type === Boolean || type === String)
            return [ss_IEquatable, ss_IComparable];
        else if (type === Array || ss.isTypedArrayType(type))
            return [ss_IEnumerable, ss_ICollection, ss_IList];
        else
            return [];
    };

    ss.isInstanceOfType = function ss$isInstanceOfType(instance, type) {
        if (ss.isNullOrUndefined(instance))
            return false;

        if (typeof (type.isInstanceOfType) === 'function')
            return type.isInstanceOfType(instance);

        return ss.isAssignableFrom(type, ss.getInstanceType(instance));
    };

    ss.isAssignableFrom = function ss$isAssignableFrom(target, type) {
        return target === type || (typeof (target.isAssignableFrom) === 'function' && target.isAssignableFrom(type)) || type.prototype instanceof target;
    };

    ss.isClass = function Type$isClass(type) {
        return (type.__class == true || type === Array || type === Function || type === RegExp || type === String || type === Error || type === Object);
    };

    ss.isEnum = function Type$isEnum(type) {
        return !!type.__enum;
    };

    ss.isFlags = function Type$isFlags(type) {
        return type.__metadata && type.__metadata.enumFlags || false;
    };

    ss.isInterface = function Type$isInterface(type) {
        return !!type.__interface;
    };

    ss.safeCast = function ss$safeCast(instance, type) {
        if (type === true)
            return instance;
        else if (type === false)
            return null;
        else
            return ss.isInstanceOfType(instance, type) ? instance : null;
    };

    ss.cast = function ss$cast(instance, type) {
        if (instance === null || typeof (instance) === 'undefined')
            return instance;
        else if (type === true || (type !== false && ss.isInstanceOfType(instance, type)))
            return instance;
        throw new ss_InvalidCastException('Cannot cast object to type ' + ss.getTypeFullName(type));
    };

    ss.getInstanceType = function ss$getInstanceType(instance) {
        if (!ss.isValue(instance))
            throw new ss_NullReferenceException('Cannot get type of null');

        // NOTE: We have to catch exceptions because the constructor
        //       cannot be looked up on native COM objects
        try {
            return instance.constructor;
        }
        catch (ex) {
            return Object;
        }
    };

    ss.getType = function ss$getType(typeName) {
        if (!typeName)
            return null;

        var arr = typeName.split(',');
        var module = (arr.length > 1 ? ss.__assemblies[arr[1].trim()] : global);
        return module ? ss.getAssemblyType(module, arr[0].trim()) : null;
    };

    ss.getDefaultValue = function ss$getDefaultValue(type) {
        if (typeof (type.getDefaultValue) === 'function')
            return type.getDefaultValue();
        else if (type === Boolean)
            return false;
        else if (type === Date)
            return new Date(0);
        else if (type === Number)
            return 0;
        return null;
    };

    ss.createInstance = function ss$createInstance(type) {
        if (typeof (type.createInstance) === 'function')
            return type.createInstance();
        else if (type === Boolean)
            return false;
        else if (type === Date)
            return new Date(0);
        else if (type === Number)
            return 0;
        else if (type === String)
            return '';
        else
            return new type();
    };

    ss.applyConstructor = function ss$applyConstructor(constructor, args) {
        var f = function () {
            constructor.apply(this, args);
        };
        f.prototype = constructor.prototype;
        return new f();
    };

    ss.getAttributes = function ss$getAttributes(type, attrType, inherit) {
        var result = [];
        if (inherit) {
            var b = ss.getBaseType(type);
            if (b) {
                var a = ss.getAttributes(b, attrType, true);
                for (var i = 0; i < a.length; i++) {
                    var t = ss.getInstanceType(a[i]);
                    if (!t.__metadata || !t.__metadata.attrNoInherit)
                        result.push(a[i]);
                }
            }
        }
        if (type.__metadata && type.__metadata.attr) {
            for (var i = 0; i < type.__metadata.attr.length; i++) {
                var a = type.__metadata.attr[i];
                if (attrType == null || ss.isInstanceOfType(a, attrType)) {
                    var t = ss.getInstanceType(a);
                    if (!t.__metadata || !t.__metadata.attrAllowMultiple) {
                        for (var j = result.length - 1; j >= 0; j--) {
                            if (ss.isInstanceOfType(result[j], t))
                                result.splice(j, 1);
                        }
                    }
                    result.push(a);
                }
            }
        }
        return result;
    };

    ss.getMembers = function ss$getMembers(type, memberTypes, bindingAttr, name, params) {
        var result = [];
        if ((bindingAttr & 72) == 72 || (bindingAttr & 6) == 4) {
            var b = ss.getBaseType(type);
            if (b)
                result = ss.getMembers(b, memberTypes & ~1, bindingAttr & (bindingAttr & 64 ? 255 : 247) & (bindingAttr & 2 ? 251 : 255), name, params);
        }

        var f = function (m) {
            if ((memberTypes & m.type) && (((bindingAttr & 4) && !m.isStatic) || ((bindingAttr & 8) && m.isStatic)) && (!name || m.name === name)) {
                if (params) {
                    if ((m.params || []).length !== params.length)
                        return;
                    for (var i = 0; i < params.length; i++) {
                        if (params[i] !== m.params[i])
                            return;
                    }
                }
                result.push(m);
            }
        };

        if (type.__metadata && type.__metadata.members) {
            for (var i = 0; i < type.__metadata.members.length; i++) {
                var m = type.__metadata.members[i];
                f(m);
                for (var j = 0; j < 4; j++) {
                    var a = ['getter', 'setter', 'adder', 'remover'][j];
                    if (m[a])
                        f(m[a]);
                }
            }
        }

        if (bindingAttr & 256) {
            while (type) {
                var r = [];
                for (var i = 0; i < result.length; i++) {
                    if (result[i].typeDef === type)
                        r.push(result[i]);
                }
                if (r.length > 1)
                    throw new ss_AmbiguousMatchException('Ambiguous match');
                else if (r.length === 1)
                    return r[0];
                type = ss.getBaseType(type);
            }
            return null;
        }

        return result;
    };

    ss.midel = function ss$midel(mi, target, typeArguments) {
        if (mi.isStatic && !!target)
            throw new ss_ArgumentException('Cannot specify target for static method');
        else if (!mi.isStatic && !target)
            throw new ss_ArgumentException('Must specify target for instance method');

        var method;
        if (mi.fget) {
            method = function () { return (mi.isStatic ? mi.typeDef : this)[mi.fget]; };
        }
        else if (mi.fset) {
            method = function (v) { (mi.isStatic ? mi.typeDef : this)[mi.fset] = v; };
        }
        else {
            method = mi.def || (mi.isStatic || mi.sm ? mi.typeDef[mi.sname] : target[mi.sname]);

            if (mi.tpcount) {
                if (!typeArguments || typeArguments.length !== mi.tpcount)
                    throw new ss_ArgumentException('Wrong number of type arguments');
                method = method.apply(null, typeArguments);
            }
            else {
                if (typeArguments && typeArguments.length)
                    throw new ss_ArgumentException('Cannot specify type arguments for non-generic method');
            }
            if (mi.exp) {
                var _m1 = method;
                method = function () { return _m1.apply(this, Array.prototype.slice.call(arguments, 0, arguments.length - 1).concat(arguments[arguments.length - 1])); };
            }
            if (mi.sm) {
                var _m2 = method;
                method = function () { return _m2.apply(null, [this].concat(Array.prototype.slice.call(arguments))); };
            }
        }
        return ss.mkdel(target, method);
    };

    ss.invokeCI = function ss$invokeCI(ci, args) {
        if (ci.exp)
            args = args.slice(0, args.length - 1).concat(args[args.length - 1]);

        if (ci.def)
            return ci.def.apply(null, args);
        else if (ci.sm)
            return ci.typeDef[ci.sname].apply(null, args);
        else
            return ss.applyConstructor(ci.sname ? ci.typeDef[ci.sname] : ci.typeDef, args);
    };

    ss.fieldAccess = function ss$fieldAccess(fi, obj) {
        if (fi.isStatic && !!obj)
            throw new ss_ArgumentException('Cannot specify target for static field');
        else if (!fi.isStatic && !obj)
            throw new ss_ArgumentException('Must specify target for instance field');
        obj = fi.isStatic ? fi.typeDef : obj;
        if (arguments.length === 3)
            obj[fi.sname] = arguments[2];
        else
            return obj[fi.sname];
    };

    ///////////////////////////////////////////////////////////////////////////////
    // IFormattable

    var ss_IFormattable = function IFormattable$() { };

    ss_IFormattable.__typeName = 'ss.IFormattable';
    ss.IFormattable = ss_IFormattable;
    ss.initInterface(ss_IFormattable, ss, { format: null });

    ss.format = function ss$format(obj, fmt) {
        if (typeof (obj) === 'number')
            return ss.formatNumber(obj, fmt);
        else if (ss.isDate(obj))
            return ss.formatDate(obj, fmt);
        else
            return obj.format(fmt);
    };

    ///////////////////////////////////////////////////////////////////////////////
    // IComparable

    var ss_IComparable = function IComparable$() { };

    ss_IComparable.__typeName = 'ss.IComparable';
    ss.IComparable = ss_IComparable;
    ss.initInterface(ss_IComparable, ss, { compareTo: null });

    ///////////////////////////////////////////////////////////////////////////////
    // IEquatable

    var ss_IEquatable = function IEquatable$() { };

    ss_IEquatable.__typeName = 'ss.IEquatable';
    ss.IEquatable = ss_IEquatable;
    ss.initInterface(ss_IEquatable, ss, { equalsT: null });

    ///////////////////////////////////////////////////////////////////////////////
    // Number Extensions

    ss.formatNumber = function ss$formatNumber(num, format) {
        if (ss.isNullOrUndefined(format) || (format.length == 0) || (format == 'i')) {
            return num.toString();
        }
        return ss.netFormatNumber(num, format, ss_CultureInfo.invariantCulture.numberFormat);
    };

    ss.localeFormatNumber = function ss$localeFormatNumber(num, format) {
        if (ss.isNullOrUndefined(format) || (format.length == 0) || (format == 'i')) {
            return num.toLocaleString();
        }
        return ss.netFormatNumber(num, format, ss_CultureInfo.currentCulture.numberFormat);
    };

    ss._commaFormatNumber = function ss$_commaFormat(number, groups, decimal, comma) {
        var decimalPart = null;
        var decimalIndex = number.indexOf(decimal);
        if (decimalIndex > 0) {
            decimalPart = number.substr(decimalIndex);
            number = number.substr(0, decimalIndex);
        }

        var negative = ss.startsWithString(number, '-');
        if (negative) {
            number = number.substr(1);
        }

        var groupIndex = 0;
        var groupSize = groups[groupIndex];
        if (number.length < groupSize) {
            return (negative ? '-' : '') + (decimalPart ? number + decimalPart : number);
        }

        var index = number.length;
        var s = '';
        var done = false;
        while (!done) {
            var length = groupSize;
            var startIndex = index - length;
            if (startIndex < 0) {
                groupSize += startIndex;
                length += startIndex;
                startIndex = 0;
                done = true;
            }
            if (!length) {
                break;
            }

            var part = number.substr(startIndex, length);
            if (s.length) {
                s = part + comma + s;
            }
            else {
                s = part;
            }
            index -= length;

            if (groupIndex < groups.length - 1) {
                groupIndex++;
                groupSize = groups[groupIndex];
            }
        }

        if (negative) {
            s = '-' + s;
        }
        return decimalPart ? s + decimalPart : s;
    };

    ss.netFormatNumber = function ss$netFormatNumber(num, format, numberFormat) {
        var nf = (numberFormat && numberFormat.getFormat(ss_NumberFormatInfo)) || ss_CultureInfo.currentCulture.numberFormat;

        var s = '';
        var precision = -1;

        if (format.length > 1) {
            precision = parseInt(format.substr(1));
        }

        var fs = format.charAt(0);
        switch (fs) {
            case 'd': case 'D':
                s = parseInt(Math.abs(num)).toString();
                if (precision != -1) {
                    s = ss.padLeftString(s, precision, 0x30);
                }
                if (num < 0) {
                    s = '-' + s;
                }
                break;
            case 'x': case 'X':
                s = parseInt(Math.abs(num)).toString(16);
                if (fs == 'X') {
                    s = s.toUpperCase();
                }
                if (precision != -1) {
                    s = ss.padLeftString(s, precision, 0x30);
                }
                break;
            case 'e': case 'E':
                if (precision == -1) {
                    s = num.toExponential();
                }
                else {
                    s = num.toExponential(precision);
                }
                if (fs == 'E') {
                    s = s.toUpperCase();
                }
                break;
            case 'f': case 'F':
            case 'n': case 'N':
                if (precision == -1) {
                    precision = nf.numberDecimalDigits;
                }
                s = num.toFixed(precision).toString();
                if (precision && (nf.numberDecimalSeparator != '.')) {
                    var index = s.indexOf('.');
                    s = s.substr(0, index) + nf.numberDecimalSeparator + s.substr(index + 1);
                }
                if ((fs == 'n') || (fs == 'N')) {
                    s = ss._commaFormatNumber(s, nf.numberGroupSizes, nf.numberDecimalSeparator, nf.numberGroupSeparator);
                }
                break;
            case 'c': case 'C':
                if (precision == -1) {
                    precision = nf.currencyDecimalDigits;
                }
                s = Math.abs(num).toFixed(precision).toString();
                if (precision && (nf.currencyDecimalSeparator != '.')) {
                    var index = s.indexOf('.');
                    s = s.substr(0, index) + nf.currencyDecimalSeparator + s.substr(index + 1);
                }
                s = ss._commaFormatNumber(s, nf.currencyGroupSizes, nf.currencyDecimalSeparator, nf.currencyGroupSeparator);
                if (num < 0) {
                    s = ss.formatString(nf.currencyNegativePattern, s);
                }
                else {
                    s = ss.formatString(nf.currencyPositivePattern, s);
                }
                break;
            case 'p': case 'P':
                if (precision == -1) {
                    precision = nf.percentDecimalDigits;
                }
                s = (Math.abs(num) * 100.0).toFixed(precision).toString();
                if (precision && (nf.percentDecimalSeparator != '.')) {
                    var index = s.indexOf('.');
                    s = s.substr(0, index) + nf.percentDecimalSeparator + s.substr(index + 1);
                }
                s = ss._commaFormatNumber(s, nf.percentGroupSizes, nf.percentDecimalSeparator, nf.percentGroupSeparator);
                if (num < 0) {
                    s = ss.formatString(nf.percentNegativePattern, s);
                }
                else {
                    s = ss.formatString(nf.percentPositivePattern, s);
                }
                break;
        }

        return s;
    };

    ///////////////////////////////////////////////////////////////////////////////
    // String Extensions
    ss.netSplit = function ss$netSplit(s, strings, limit, options) {
        var re = new RegExp(strings.map(ss.regexpEscape).join('|'), 'g'), res = [], m, i;
        for (i = 0; ; i = re.lastIndex) {
            if (m = re.exec(s)) {
                if (options !== 1 || m.index > i) {
                    if (res.length === limit - 1) {
                        res.push(s.substr(i));
                        return res;
                    }
                    else
                        res.push(s.substring(i, m.index));
                }
            }
            else {
                if (options !== 1 || i !== s.length)
                    res.push(s.substr(i));
                return res;
            }
        }
    };

    ss.compareStrings = function ss$compareStrings(s1, s2, ignoreCase) {
        if (ignoreCase) {
            if (s1) {
                s1 = s1.toUpperCase();
            }
            if (s2) {
                s2 = s2.toUpperCase();
            }
        }
        s1 = s1 || '';
        s2 = s2 || '';

        if (s1 == s2) {
            return 0;
        }
        if (s1 < s2) {
            return -1;
        }
        return 1;
    };

    ss.endsWithString = function ss$endsWithString(s, suffix) {
        if (!suffix.length) {
            return true;
        }
        if (suffix.length > s.length) {
            return false;
        }
        return (s.substr(s.length - suffix.length) == suffix);
    };

    ss._formatString = function ss$_formatString(format, values, useLocale) {
        if (!ss._formatRE) {
            ss._formatRE = /\{\{|\}\}|\{[^\}\{]+\}/g;
        }

        return format.replace(ss._formatRE,
            function (m) {
                if (m === '{{' || m === '}}')
                    return m.charAt(0);
                var index = parseInt(m.substr(1));
                var value = values[index + 1];
                if (ss.isNullOrUndefined(value)) {
                    return '';
                }
                if (ss.isInstanceOfType(value, ss_IFormattable)) {
                    var formatSpec = null;
                    var formatIndex = m.indexOf(':');
                    if (formatIndex > 0) {
                        formatSpec = m.substring(formatIndex + 1, m.length - 1);
                    }
                    return ss.format(value, formatSpec);
                }
                else {
                    return useLocale ? value.toLocaleString() : value.toString();
                }
            });
    };

    ss.formatString = function String$format(format) {
        return ss._formatString(format, arguments, /* useLocale */ false);
    };

    ss.stringFromChar = function ss$stringFromChar(ch, count) {
        var s = ch;
        for (var i = 1; i < count; i++) {
            s += ch;
        }
        return s;
    };

    ss.htmlDecode = function ss$htmlDecode(s) {
        return s.replace(/&([^;]+);/g, function (_, e) {
            if (e[0] === '#')
                return String.fromCharCode(parseInt(e.substr(1)));
            switch (e) {
                case 'quot': return '"';
                case 'apos': return "'";
                case 'amp': return '&';
                case 'lt': return '<';
                case 'gt': return '>';
                default: return '&' + e + ';';
            }
        });
    };

    ss.htmlEncode = function ss$htmlEncode(s) {
        return s.replace(/&/g, '&amp;').replace(/"/g, '&quot;').replace(/'/g, '&#39;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
    };

    ss.jsEncode = function ss$jsEncode(s, q) {
        s = s.replace(/\\/g, '\\\\').replace(/'/g, "\\'").replace(/"/g, '\\"');
        return q ? '"' + s + '"' : s;
    };

    ss.indexOfAnyString = function ss$indexOfAnyString(s, chars, startIndex, count) {
        var length = s.length;
        if (!length) {
            return -1;
        }

        chars = String.fromCharCode.apply(null, chars);
        startIndex = startIndex || 0;
        count = count || length;

        var endIndex = startIndex + count - 1;
        if (endIndex >= length) {
            endIndex = length - 1;
        }

        for (var i = startIndex; i <= endIndex; i++) {
            if (chars.indexOf(s.charAt(i)) >= 0) {
                return i;
            }
        }
        return -1;
    };

    ss.insertString = function ss$insertString(s, index, value) {
        if (!value) {
            return s;
        }
        if (!index) {
            return value + s;
        }
        var s1 = s.substr(0, index);
        var s2 = s.substr(index);
        return s1 + value + s2;
    };

    ss.isNullOrEmptyString = function ss$isNullOrEmptyString(s) {
        return !s || !s.length;
    };

    ss.lastIndexOfAnyString = function ss$lastIndexOfAnyString(s, chars, startIndex, count) {
        var length = s.length;
        if (!length) {
            return -1;
        }

        chars = String.fromCharCode.apply(null, chars);
        startIndex = startIndex || length - 1;
        count = count || length;

        var endIndex = startIndex - count + 1;
        if (endIndex < 0) {
            endIndex = 0;
        }

        for (var i = startIndex; i >= endIndex; i--) {
            if (chars.indexOf(s.charAt(i)) >= 0) {
                return i;
            }
        }
        return -1;
    };

    ss.localeFormatString = function ss$localeFormatString(format) {
        return ss._formatString(format, arguments, /* useLocale */ true);
    };

    ss.padLeftString = function ss$padLeftString(s, totalWidth, ch) {
        if (s.length < totalWidth) {
            ch = String.fromCharCode(ch || 0x20);
            return ss.stringFromChar(ch, totalWidth - s.length) + s;
        }
        return s;
    };

    ss.padRightString = function ss$padRightString(s, totalWidth, ch) {
        if (s.length < totalWidth) {
            ch = String.fromCharCode(ch || 0x20);
            return s + ss.stringFromChar(ch, totalWidth - s.length);
        }
        return s;
    };

    ss.removeString = function ss$removeString(s, index, count) {
        if (!count || ((index + count) > this.length)) {
            return s.substr(0, index);
        }
        return s.substr(0, index) + s.substr(index + count);
    };

    ss.replaceAllString = function ss$replaceAllString(s, oldValue, newValue) {
        newValue = newValue || '';
        return s.split(oldValue).join(newValue);
    };

    ss.startsWithString = function ss$startsWithString(s, prefix) {
        if (!prefix.length) {
            return true;
        }
        if (prefix.length > s.length) {
            return false;
        }
        return (s.substr(0, prefix.length) == prefix);
    };

    if (!String.prototype.trim) {
        String.prototype.trim = function String$trim() {
            return ss.trimStartString(ss.trimEndString(this));
        };
    }

    ss.trimEndString = function ss$trimEndString(s, chars) {
        return s.replace(chars ? new RegExp('[' + String.fromCharCode.apply(null, chars) + ']+$') : /\s*$/, '');
    };

    ss.trimStartString = function ss$trimStartString(s, chars) {
        return s.replace(chars ? new RegExp('^[' + String.fromCharCode.apply(null, chars) + ']+') : /^\s*/, '');
    };

    ss.trimString = function ss$trimString(s, chars) {
        return ss.trimStartString(ss.trimEndString(s, chars), chars);
    };

    ss.lastIndexOfString = function ss$lastIndexOfString(s, search, startIndex, count) {
        var index = s.lastIndexOf(search, startIndex);
        return (index < (startIndex - count + 1)) ? -1 : index;
    };

    ss.indexOfString = function ss$indexOfString(s, search, startIndex, count) {
        var index = s.indexOf(search, startIndex);
        return ((index + search.length) <= (startIndex + count)) ? index : -1;
    };

    ///////////////////////////////////////////////////////////////////////////////
    // Math Extensions

    ss.divRem = function ss$divRem(a, b, result) {
        var remainder = a % b;
        result.$ = remainder;
        return (a - remainder) / b;
    };

    ss.round = function ss$round(n, d, rounding) {
        var m = Math.pow(10, d || 0);
        n *= m;
        var sign = (n > 0) | -(n < 0);
        if (n % 1 === 0.5 * sign) {
            var f = Math.floor(n);
            return (f + (rounding ? (sign > 0) : (f % 2 * sign))) / m;
        }

        return Math.round(n) / m;
    };

    ///////////////////////////////////////////////////////////////////////////////
    // IFormatProvider

    var ss_IFormatProvider = function IFormatProvider$() { };

    ss_IFormatProvider.__typeName = 'ss.IFormatProvider';
    ss.IFormatProvider = ss_IFormatProvider;
    ss.initInterface(ss_IFormatProvider, ss, { getFormat: null });

    ///////////////////////////////////////////////////////////////////////////////
    // NumberFormatInfo

    var ss_NumberFormatInfo = function NumberFormatInfo$() {
    };

    ss_NumberFormatInfo.__typeName = 'ss.NumberFormatInfo';
    ss.NumberFormatInfo = ss_NumberFormatInfo;
    ss.initClass(ss_NumberFormatInfo, ss, {
        getFormat: function NumberFormatInfo$getFormat(type) {
            return (type === ss_NumberFormatInfo) ? this : null;
        }
    }, null, [ss_IFormatProvider]);

    ss_NumberFormatInfo.invariantInfo = new ss_NumberFormatInfo();
    ss.shallowCopy({
        naNSymbol: 'NaN',
        negativeSign: '-',
        positiveSign: '+',
        negativeInfinitySymbol: '-Infinity',
        positiveInfinitySymbol: 'Infinity',

        percentSymbol: '%',
        percentGroupSizes: [3],
        percentDecimalDigits: 2,
        percentDecimalSeparator: '.',
        percentGroupSeparator: ',',
        percentPositivePattern: 0,
        percentNegativePattern: 0,

        currencySymbol: '$',
        currencyGroupSizes: [3],
        currencyDecimalDigits: 2,
        currencyDecimalSeparator: '.',
        currencyGroupSeparator: ',',
        currencyNegativePattern: 0,
        currencyPositivePattern: 0,

        numberGroupSizes: [3],
        numberDecimalDigits: 2,
        numberDecimalSeparator: '.',
        numberGroupSeparator: ','
    }, ss_NumberFormatInfo.invariantInfo);

    ///////////////////////////////////////////////////////////////////////////////
    // DateTimeFormatInfo

    var ss_DateTimeFormatInfo = function DateTimeFormatInfo$() {
    };

    ss_DateTimeFormatInfo.__typeName = 'ss.DateTimeFormatInfo';
    ss.DateTimeFormatInfo = ss_DateTimeFormatInfo;
    ss.initClass(ss_DateTimeFormatInfo, ss, {
        getFormat: function DateTimeFormatInfo$getFormat(type) {
            return type === ss_DateTimeFormatInfo ? this : null;
        }
    }, null, [ss_IFormatProvider]);

    ss_DateTimeFormatInfo.invariantInfo = new ss_DateTimeFormatInfo();
    ss.shallowCopy({
        amDesignator: 'AM',
        pmDesignator: 'PM',

        dateSeparator: '/',
        timeSeparator: ':',

        gmtDateTimePattern: 'ddd, dd MMM yyyy HH:mm:ss \'GMT\'',
        universalDateTimePattern: 'yyyy-MM-dd HH:mm:ssZ',
        sortableDateTimePattern: 'yyyy-MM-ddTHH:mm:ss',
        dateTimePattern: 'dddd, MMMM dd, yyyy h:mm:ss tt',

        longDatePattern: 'dddd, MMMM dd, yyyy',
        shortDatePattern: 'M/d/yyyy',

        longTimePattern: 'h:mm:ss tt',
        shortTimePattern: 'h:mm tt',

        firstDayOfWeek: 0,
        dayNames: ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
        shortDayNames: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
        minimizedDayNames: ['Su', 'Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa'],

        monthNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December', ''],
        shortMonthNames: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec', '']
    }, ss_DateTimeFormatInfo.invariantInfo);

    ///////////////////////////////////////////////////////////////////////////////
    // Stopwatch

    var ss_Stopwatch = function Stopwatch$() {
        this._stopTime = 0;
        this._startTime = 0;
        this.isRunning = false;
    };

    ss_Stopwatch.startNew = function Stopwatch$startNew() {
        var s = new ss_Stopwatch();
        s.start();
        return s;
    };

    if (typeof (window) !== 'undefined' && window.performance && window.performance.now) {
        ss_Stopwatch.frequency = 1e6;
        ss_Stopwatch.isHighResolution = true;
        ss_Stopwatch.getTimestamp = function () { return Math.round(window.performance.now() * 1000); };
    }
    else if (typeof (process) !== 'undefined' && process.hrtime) {
        ss_Stopwatch.frequency = 1e9;
        ss_Stopwatch.isHighResolution = true;
        ss_Stopwatch.getTimestamp = function () { var hr = process.hrtime(); return hr[0] * 1e9 + hr[1]; };
    }
    else {
        ss_Stopwatch.frequency = 1e3;
        ss_Stopwatch.isHighResolution = false;
        ss_Stopwatch.getTimestamp = function () { return new Date().valueOf(); };
    }

    ss_Stopwatch.__typeName = 'ss.Stopwatch';
    ss.Stopwatch = ss_Stopwatch;
    ss.initClass(ss_Stopwatch, ss, {
        reset: function Stopwatch$reset() {
            this._stopTime = this._startTime = ss_Stopwatch.getTimestamp();
            this.isRunning = false;
        },

        ticks: function Stopwatch$ticks() {
            return (this.isRunning ? ss_Stopwatch.getTimestamp() : this._stopTime) - this._startTime;
        },

        milliseconds: function Stopwatch$milliseconds() {
            return Math.round(this.ticks() / ss_Stopwatch.frequency * 1000);
        },

        timeSpan: function Stopwatch$timeSpan() {
            return new ss_TimeSpan(this.milliseconds() * 10000);
        },

        start: function Stopwatch$start() {
            if (this.isRunning)
                return;
            this._startTime = ss_Stopwatch.getTimestamp();
            this.isRunning = true;
        },

        stop: function Stopwatch$stop() {
            if (!this.isRunning)
                return;
            this._stopTime = ss_Stopwatch.getTimestamp();
            this.isRunning = false;
        },

        restart: function Stopwatch$restart() {
            this.isRunning = false;
            this.start();
        }
    });

    ///////////////////////////////////////////////////////////////////////////////
    // Array Extensions

    ss._flatIndex = function ss$_flatIndex(arr, indices) {
        if (indices.length != (arr._sizes ? arr._sizes.length : 1))
            throw new ss_ArgumentException('Invalid number of indices');

        if (indices[0] < 0 || indices[0] >= (arr._sizes ? arr._sizes[0] : arr.length))
            throw new ss_ArgumentException('Index 0 out of range');

        var idx = indices[0];
        if (arr._sizes) {
            for (var i = 1; i < arr._sizes.length; i++) {
                if (indices[i] < 0 || indices[i] >= arr._sizes[i])
                    throw new ss_ArgumentException('Index ' + i + ' out of range');
                idx = idx * arr._sizes[i] + indices[i];
            }
        }
        return idx;
    };

    ss.arrayGet2 = function ss$arrayGet2(arr, indices) {
        var idx = ss._flatIndex(arr, indices);
        var r = arr[idx];
        return typeof r !== 'undefined' ? r : arr._defvalue;
    };

    ss.arrayGet = function ss$arrayGet(arr) {
        return ss.arrayGet2(arr, Array.prototype.slice.call(arguments, 1));
    }

    ss.arraySet2 = function ss$arraySet2(arr, value, indices) {
        var idx = ss._flatIndex(arr, indices);
        arr[idx] = value;
    };

    ss.arraySet = function ss$arraySet() {
        return ss.arraySet2(arguments[0], arguments[arguments.length - 1], Array.prototype.slice.call(arguments, 1, arguments.length - 1));
    };

    ss.arrayRank = function ss$arrayRank(arr) {
        return arr._sizes ? arr._sizes.length : 1;
    };

    ss.arrayLength = function ss$arrayLength(arr, dimension) {
        if (dimension >= (arr._sizes ? arr._sizes.length : 1))
            throw new ss_ArgumentException('Invalid dimension');
        return arr._sizes ? arr._sizes[dimension] : arr.length;
    };

    ss.arrayExtract = function ss$arrayExtract(arr, start, count) {
        if (!ss.isValue(count)) {
            return arr.slice(start);
        }
        return arr.slice(start, start + count);
    };

    ss.arrayAddRange = function ss$arrayAddRange(arr, items) {
        if (items instanceof Array) {
            arr.push.apply(arr, items);
        }
        else {
            var e = ss.getEnumerator(items);
            try {
                while (e.moveNext()) {
                    ss.add(arr, e.current());
                }
            }
            finally {
                if (ss.isInstanceOfType(e, ss_IDisposable)) {
                    ss.cast(e, ss_IDisposable).dispose();
                }
            }
        }
    };

    ss.arrayClone = function ss$arrayClone(arr) {
        if (arr.length === 1) {
            return [arr[0]];
        }
        else {
            return Array.apply(null, arr);
        }
    };

    ss.arrayPeekFront = function ss$arrayPeekFront(arr) {
        if (arr.length)
            return arr[0];
        throw new ss_InvalidOperationException('Array is empty');
    };

    ss.arrayPeekBack = function ss$arrayPeekBack(arr) {
        if (arr.length)
            return arr[arr.length - 1];
        throw new ss_InvalidOperationException('Array is empty');
    };

    ss.indexOfArray = function ss$indexOfArray(arr, item, startIndex) {
        startIndex = startIndex || 0;
        for (var i = startIndex; i < arr.length; i++) {
            if (ss.staticEquals(arr[i], item)) {
                return i;
            }
        }
        return -1;
    }

    ss.arrayInsertRange = function ss$arrayInsertRange(arr, index, items) {
        if (items instanceof Array) {
            if (index === 0) {
                arr.unshift.apply(arr, items);
            }
            else {
                for (var i = 0; i < items.length; i++) {
                    arr.splice(index + i, 0, items[i]);
                }
            }
        }
        else {
            var e = ss.getEnumerator(items);
            try {
                while (e.moveNext()) {
                    arr.insert(index, e.current());
                    index++;
                }
            }
            finally {
                if (ss.isInstanceOfType(e, ss_IDisposable)) {
                    ss.cast(e, ss_IDisposable).dispose();
                }
            }
        }
    };

    if (!Array.prototype.map) {
        Array.prototype.map = function Array$map(callback, instance) {
            var length = this.length;
            var mapped = new Array(length);
            for (var i = 0; i < length; i++) {
                if (i in this) {
                    mapped[i] = callback.call(instance, this[i], i, this);
                }
            }
            return mapped;
        };
    }

    ss.arrayRemoveRange = function ss$arrayRemoveRange(arr, index, count) {
        arr.splice(index, count);
    };

    if (!Array.prototype.some) {
        Array.prototype.some = function Array$some(callback, instance) {
            var length = this.length;
            for (var i = 0; i < length; i++) {
                if (i in this && callback.call(instance, this[i], i, this)) {
                    return true;
                }
            }
            return false;
        };
    }

    ss.arrayFromEnumerable = function ss$arrayFromEnumerable(enm) {
        if (!ss.isValue(enm))
            return null;

        var e = ss.getEnumerator(enm), r = [];
        try {
            while (e.moveNext())
                r.push(e.current());
        }
        finally {
            e.dispose();
        }
        return r;
    };

    ss.multidimArray = function ss$multidimArray(defvalue, sizes) {
        var arr = [];
        arr._defvalue = defvalue;
        arr._sizes = [arguments[1]];
        var length = arguments[1];
        for (var i = 2; i < arguments.length; i++) {
            length *= arguments[i];
            arr._sizes[i - 1] = arguments[i];
        }
        arr.length = length;
        return arr;
    };

    ss.repeat = function ss$repeat(value, count) {
        var result = [];
        for (var i = 0; i < count; i++)
            result.push(value);
        return result;
    };

    ///////////////////////////////////////////////////////////////////////////////
    // Date Extensions

    ss.utcNow = function ss$utcNow() {
        var d = new Date();
        return new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds());
    };

    ss.toUTC = function ss$toUniversalTime(d) {
        return new Date(d.getUTCFullYear(), d.getUTCMonth(), d.getUTCDate(), d.getUTCHours(), d.getUTCMinutes(), d.getUTCSeconds(), d.getUTCMilliseconds());
    };

    ss.fromUTC = function ss$toLocalTime(d) {
        return new Date(Date.UTC(d.getFullYear(), d.getMonth(), d.getDate(), d.getHours(), d.getMinutes(), d.getSeconds(), d.getMilliseconds()));
    };

    ss.today = function ss$today() {
        var d = new Date();
        return new Date(d.getFullYear(), d.getMonth(), d.getDate());
    }

    ss.formatDate = function ss$formatDate(date, format) {
        if (ss.isNullOrUndefined(format) || (format.length == 0) || (format == 'i')) {
            return date.toString();
        }
        if (format == 'id') {
            return date.toDateString();
        }
        if (format == 'it') {
            return date.toTimeString();
        }

        return ss._netFormatDate(date, format, false);
    };

    ss.localeFormatDate = function ss$localeFormatDate(date, format) {
        if (ss.isNullOrUndefined(format) || (format.length == 0) || (format == 'i')) {
            return date.toLocaleString();
        }
        if (format == 'id') {
            return date.toLocaleDateString();
        }
        if (format == 'it') {
            return date.toLocaleTimeString();
        }

        return ss._netFormatDate(date, format, true);
    };

    ss._netFormatDate = function ss$_netFormatDate(dt, format, useLocale) {
        var dtf = useLocale ? ss_CultureInfo.currentCulture.dateTimeFormat : ss_CultureInfo.invariantCulture.dateTimeFormat;

        if (format.length == 1) {
            switch (format) {
                case 'f': format = dtf.longDatePattern + ' ' + dtf.shortTimePattern; break;
                case 'F': format = dtf.dateTimePattern; break;

                case 'd': format = dtf.shortDatePattern; break;
                case 'D': format = dtf.longDatePattern; break;

                case 't': format = dtf.shortTimePattern; break;
                case 'T': format = dtf.longTimePattern; break;

                case 'g': format = dtf.shortDatePattern + ' ' + dtf.shortTimePattern; break;
                case 'G': format = dtf.shortDatePattern + ' ' + dtf.longTimePattern; break;

                case 'R': case 'r':
                    dtf = ss_CultureInfo.InvariantCulture.dateTimeFormat;
                    format = dtf.gmtDateTimePattern;
                    break;
                case 'u': format = dtf.universalDateTimePattern; break;
                case 'U':
                    format = dtf.dateTimePattern;
                    dt = new Date(dt.getUTCFullYear(), dt.getUTCMonth(), dt.getUTCDate(),
                                  dt.getUTCHours(), dt.getUTCMinutes(), dt.getUTCSeconds(), dt.getUTCMilliseconds());
                    break;

                case 's': format = dtf.sortableDateTimePattern; break;
            }
        }

        if (format.charAt(0) == '%') {
            format = format.substr(1);
        }

        if (!Date._formatRE) {
            Date._formatRE = /'.*?[^\\]'|dddd|ddd|dd|d|MMMM|MMM|MM|M|yyyy|yy|y|hh|h|HH|H|mm|m|ss|s|tt|t|fff|ff|f|zzz|zz|z/g;
        }

        var re = Date._formatRE;
        var sb = new ss_StringBuilder();

        re.lastIndex = 0;
        while (true) {
            var index = re.lastIndex;
            var match = re.exec(format);

            sb.append(format.slice(index, match ? match.index : format.length));
            if (!match) {
                break;
            }

            var fs = match[0];
            var part = fs;
            switch (fs) {
                case 'dddd':
                    part = dtf.dayNames[dt.getDay()];
                    break;
                case 'ddd':
                    part = dtf.shortDayNames[dt.getDay()];
                    break;
                case 'dd':
                    part = ss.padLeftString(dt.getDate().toString(), 2, 0x30);
                    break;
                case 'd':
                    part = dt.getDate();
                    break;
                case 'MMMM':
                    part = dtf.monthNames[dt.getMonth()];
                    break;
                case 'MMM':
                    part = dtf.shortMonthNames[dt.getMonth()];
                    break;
                case 'MM':
                    part = ss.padLeftString((dt.getMonth() + 1).toString(), 2, 0x30);
                    break;
                case 'M':
                    part = (dt.getMonth() + 1);
                    break;
                case 'yyyy':
                    part = dt.getFullYear();
                    break;
                case 'yy':
                    part = ss.padLeftString((dt.getFullYear() % 100).toString(), 2, 0x30);
                    break;
                case 'y':
                    part = (dt.getFullYear() % 100);
                    break;
                case 'h': case 'hh':
                    part = dt.getHours() % 12;
                    if (!part) {
                        part = '12';
                    }
                    else if (fs == 'hh') {
                        part = ss.padLeftString(part.toString(), 2, 0x30);
                    }
                    break;
                case 'HH':
                    part = ss.padLeftString(dt.getHours().toString(), 2, 0x30);
                    break;
                case 'H':
                    part = dt.getHours();
                    break;
                case 'mm':
                    part = ss.padLeftString(dt.getMinutes().toString(), 2, 0x30);
                    break;
                case 'm':
                    part = dt.getMinutes();
                    break;
                case 'ss':
                    part = ss.padLeftString(dt.getSeconds().toString(), 2, 0x30);
                    break;
                case 's':
                    part = dt.getSeconds();
                    break;
                case 't': case 'tt':
                    part = (dt.getHours() < 12) ? dtf.amDesignator : dtf.pmDesignator;
                    if (fs == 't') {
                        part = part.charAt(0);
                    }
                    break;
                case 'fff':
                    part = ss.padLeftString(dt.getMilliseconds().toString(), 3, 0x30);
                    break;
                case 'ff':
                    part = ss.padLeftString(dt.getMilliseconds().toString(), 3).substr(0, 2);
                    break;
                case 'f':
                    part = ss.padLeftString(dt.getMilliseconds().toString(), 3).charAt(0);
                    break;
                case 'z':
                    part = dt.getTimezoneOffset() / 60;
                    part = ((part >= 0) ? '-' : '+') + Math.floor(Math.abs(part));
                    break;
                case 'zz': case 'zzz':
                    part = dt.getTimezoneOffset() / 60;
                    part = ((part >= 0) ? '-' : '+') + Math.floor(ss.padLeftString(Math.abs(part)).toString(), 2, 0x30);
                    if (fs == 'zzz') {
                        part += dtf.timeSeparator + Math.abs(ss.padLeftString(dt.getTimezoneOffset() % 60).toString(), 2, 0x30);
                    }
                    break;
                default:
                    if (part.charAt(0) == '\'') {
                        part = part.substr(1, part.length - 2).replace(/\\'/g, '\'');
                    }
                    break;
            }
            sb.append(part);
        }

        return sb.toString();
    };

    ss._parseExactDate = function ss$_parseExactDate(val, format, provider, utc) {
        provider = (provider && provider.getFormat(ss_DateTimeFormatInfo)) || ss_CultureInfo.currentCulture.dateTimeFormat;
        var AM = provider.amDesignator, PM = provider.pmDesignator;

        var _isInteger = function (val) {
            var digits = "1234567890";
            for (var i = 0; i < val.length; i++) {
                if (digits.indexOf(val.charAt(i)) == -1) {
                    return false;
                }
            }
            return true;
        };

        var _getInt = function (str, i, minlength, maxlength) {
            for (var x = maxlength; x >= minlength; x--) {
                var token = str.substring(i, i + x);
                if (token.length < minlength) {
                    return null;
                }
                if (_isInteger(token)) {
                    return token;
                }
            }
            return null;
        };

        val = val + "";
        format = format + "";
        var i_val = 0;
        var i_format = 0;
        var c = "";
        var token = "";

        var year = 0, month = 1, date = 1, hh = 0, mm = 0, _ss = 0, ampm = "";

        while (i_format < format.length) {
            // Get next token from format string
            c = format.charAt(i_format);
            token = "";
            while ((format.charAt(i_format) == c) && (i_format < format.length)) {
                token += format.charAt(i_format++);
            }
            // Extract contents of value based on format token
            if (token == "yyyy" || token == "yy" || token == "y") {
                if (token == "yyyy")
                    year = _getInt(val, i_val, 4, 4);
                if (token == "yy")
                    year = _getInt(val, i_val, 2, 2);
                if (token == "y")
                    year = _getInt(val, i_val, 2, 4);

                if (year == null)
                    return null;

                i_val += year.length;
                if (year.length == 2) {
                    if (year > 30) {
                        year = 1900 + (year - 0);
                    }
                    else {
                        year = 2000 + (year - 0);
                    }
                }
            }
            else if (token == "MM" || token == "M") {
                month = _getInt(val, i_val, token.length, 2);
                if (month == null || (month < 1) || (month > 12))
                    return null;
                i_val += month.length;
            }
            else if (token == "dd" || token == "d") {
                date = _getInt(val, i_val, token.length, 2);
                if (date == null || (date < 1) || (date > 31))
                    return null;
                i_val += date.length;
            }
            else if (token == "hh" || token == "h") {
                hh = _getInt(val, i_val, token.length, 2);
                if (hh == null || (hh < 1) || (hh > 12))
                    return null;
                i_val += hh.length;
            }
            else if (token == "HH" || token == "H") {
                hh = _getInt(val, i_val, token.length, 2);
                if (hh == null || (hh < 0) || (hh > 23))
                    return null;
                i_val += hh.length;
            }
            else if (token == "mm" || token == "m") {
                mm = _getInt(val, i_val, token.length, 2);
                if (mm == null || (mm < 0) || (mm > 59))
                    return null;
                i_val += mm.length;
            }
            else if (token == "ss" || token == "s") {
                _ss = _getInt(val, i_val, token.length, 2);
                if (_ss == null || (_ss < 0) || (_ss > 59))
                    return null;
                i_val += _ss.length;
            }
            else if (token == "t") {
                if (val.substring(i_val, i_val + 1).toLowerCase() == AM.charAt(0).toLowerCase())
                    ampm = AM;
                else if (val.substring(i_val, i_val + 1).toLowerCase() == PM.charAt(0).toLowerCase())
                    ampm = PM;
                else
                    return null;
                i_val += 1;
            }
            else if (token == "tt") {
                if (val.substring(i_val, i_val + 2).toLowerCase() == AM.toLowerCase())
                    ampm = AM;
                else if (val.substring(i_val, i_val + 2).toLowerCase() == PM.toLowerCase())
                    ampm = PM;
                else
                    return null;
                i_val += 2;
            }
            else {
                if (val.substring(i_val, i_val + token.length) != token)
                    return null;
                else
                    i_val += token.length;
            }
        }
        // If there are any trailing characters left in the value, it doesn't match
        if (i_val != val.length)
            return null;

        // Is date valid for month?
        if (month == 2) {
            // Check for leap year
            if (((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)) { // leap year
                if (date > 29)
                    return null;
            }
            else if (date > 28)
                return null;
        }
        if ((month == 4) || (month == 6) || (month == 9) || (month == 11)) {
            if (date > 30) {
                return null;
            }
        }
        // Correct hours value
        if (hh < 12 && ampm == PM) {
            hh = hh - 0 + 12;
        }
        else if (hh > 11 && ampm == AM) {
            hh -= 12;
        }

        if (utc)
            return new Date(Date.UTC(year, month - 1, date, hh, mm, _ss));
        else
            return new Date(year, month - 1, date, hh, mm, _ss);
    };

    ss.parseExactDate = function ss$parseExactDate(val, format, provider) {
        return ss._parseExactDate(val, format, provider, false);
    };

    ss.parseExactDateUTC = function ss$parseExactDateUTC(val, format, provider) {
        return ss._parseExactDate(val, format, provider, true);
    };

    ///////////////////////////////////////////////////////////////////////////////
    // Function Extensions

    ss._delegateContains = function ss$_delegateContains(targets, object, method) {
        for (var i = 0; i < targets.length; i += 2) {
            if (targets[i] === object && targets[i + 1] === method) {
                return true;
            }
        }
        return false;
    };

    ss._mkdel = function ss$_mkdel(targets) {
        var delegate = function () {
            if (targets.length == 2) {
                return targets[1].apply(targets[0], arguments);
            }
            else {
                var clone = ss.arrayClone(targets);
                for (var i = 0; i < clone.length; i += 2) {
                    if (ss._delegateContains(targets, clone[i], clone[i + 1])) {
                        clone[i + 1].apply(clone[i], arguments);
                    }
                }
                return null;
            }
        };
        delegate._targets = targets;

        return delegate;
    };

    ss.mkdel = function ss$mkdel(object, method) {
        if (!object) {
            return method;
        }
        return ss._mkdel([object, method]);
    };

    ss.delegateCombine = function ss$delegateCombine(delegate1, delegate2) {
        if (!delegate1) {
            if (!delegate2._targets) {
                return ss.mkdel(null, delegate2);
            }
            return delegate2;
        }
        if (!delegate2) {
            if (!delegate1._targets) {
                return ss.mkdel(null, delegate1);
            }
            return delegate1;
        }

        var targets1 = delegate1._targets ? delegate1._targets : [null, delegate1];
        var targets2 = delegate2._targets ? delegate2._targets : [null, delegate2];

        return ss._mkdel(targets1.concat(targets2));
    };

    ss.delegateRemove = function ss$delegateRemove(delegate1, delegate2) {
        if (!delegate1 || (delegate1 === delegate2)) {
            return null;
        }
        if (!delegate2) {
            return delegate1;
        }

        var targets = delegate1._targets;
        var object = null;
        var method;
        if (delegate2._targets) {
            object = delegate2._targets[0];
            method = delegate2._targets[1];
        }
        else {
            method = delegate2;
        }

        for (var i = 0; i < targets.length; i += 2) {
            if ((targets[i] === object) && (targets[i + 1] === method)) {
                if (targets.length == 2) {
                    return null;
                }
                var t = ss.arrayClone(targets);
                t.splice(i, 2);
                return ss._mkdel(t);
            }
        }

        return delegate1;
    };

    ss.delegateEquals = function ss$delegateEquals(a, b) {
        if (a === b)
            return true;
        if (!a._targets && !b._targets)
            return false;
        var ta = a._targets || [null, a], tb = b._targets || [null, b];
        if (ta.length != tb.length)
            return false;
        for (var i = 0; i < ta.length; i++) {
            if (ta[i] !== tb[i])
                return false;
        }
        return true;
    };

    ss.delegateClone = function ss$delegateClone(source) {
        return source._targets ? ss._mkdel(source._targets) : function () { return source.apply(this, arguments); };
    };

    ss.thisFix = function ss$thisFix(source) {
        return function () {
            var x = [this];
            for (var i = 0; i < arguments.length; i++)
                x.push(arguments[i]);
            return source.apply(source, x);
        };
    };

    ss.getInvocationList = function ss$getInvocationList(delegate) {
        if (!delegate._targets)
            return [delegate];
        var result = [];
        for (var i = 0; i < delegate._targets.length; i += 2)
            result.push(ss.mkdel(delegate._targets[i], delegate._targets[i + 1]));
        return result;
    };

    ///////////////////////////////////////////////////////////////////////////////
    // RegExp Extensions
    ss.regexpEscape = function ss$regexpEscape(s) {
        return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
    };

    ///////////////////////////////////////////////////////////////////////////////
    // Debug Extensions

    ss.Debug = global.Debug || function () { };
    ss.Debug.__typeName = 'Debug';

    if (!ss.Debug.writeln) {
        ss.Debug.writeln = function Debug$writeln(text) {
            if (global.console) {
                if (global.console.debug) {
                    global.console.debug(text);
                    return;
                }
                else if (global.console.log) {
                    global.console.log(text);
                    return;
                }
            }
            else if (global.opera &&
                global.opera.postError) {
                global.opera.postError(text);
                return;
            }
        }
    };

    ss.Debug._fail = function Debug$_fail(message) {
        ss.Debug.writeln(message);
        debugger;
    };

    ss.Debug.assert = function Debug$assert(condition, message) {
        if (!condition) {
            message = 'Assert failed: ' + message;
            if (confirm(message + '\r\n\r\nBreak into debugger?')) {
                ss.Debug._fail(message);
            }
        }
    };

    ss.Debug.fail = function Debug$fail(message) {
        ss.Debug._fail(message);
    };

    ///////////////////////////////////////////////////////////////////////////////
    // Enum

    var ss_Enum = function Enum$() {
    };
    ss_Enum.__typeName = 'ss.Enum';
    ss.Enum = ss_Enum;
    ss.initClass(ss_Enum, ss, {});

    ss_Enum.parse = function Enum$parse(enumType, s) {
        var values = enumType.prototype;
        if (!ss.isFlags(enumType)) {
            for (var f in values) {
                if (f === s) {
                    return values[f];
                }
            }
        }
        else {
            var parts = s.split('|');
            var value = 0;
            var parsed = true;

            for (var i = parts.length - 1; i >= 0; i--) {
                var part = parts[i].trim();
                var found = false;

                for (var f in values) {
                    if (f === part) {
                        value |= values[f];
                        found = true;
                        break;
                    }
                }
                if (!found) {
                    parsed = false;
                    break;
                }
            }

            if (parsed) {
                return value;
            }
        }
        throw new ss_ArgumentException('Invalid Enumeration Value');
    };

    ss_Enum.toString = function Enum$toString(enumType, value) {
        var values = enumType.prototype;
        if (!ss.isFlags(enumType) || (value === 0)) {
            for (var i in values) {
                if (values[i] === value) {
                    return i;
                }
            }
            throw new ss_ArgumentException('Invalid Enumeration Value');
        }
        else {
            var parts = [];
            for (var i in values) {
                if (values[i] & value) {
                    ss.add(parts, i);
                }
            }
            if (!parts.length) {
                throw new ss_ArgumentException('Invalid Enumeration Value');
            }
            return parts.join(' | ');
        }
    };

    ss_Enum.getValues = function Enum$getValues(enumType) {
        var parts = [];
        var values = enumType.prototype;
        for (var i in values) {
            if (values.hasOwnProperty(i))
                parts.push(values[i]);
        }
        return parts;
    };

    ///////////////////////////////////////////////////////////////////////////////
    // CultureInfo

    var ss_CultureInfo = function CultureInfo$(name, numberFormat, dateTimeFormat) {
        this.name = name;
        this.numberFormat = numberFormat;
        this.dateTimeFormat = dateTimeFormat;
    };

    ss_CultureInfo.__typeName = 'ss.CultureInfo';
    ss.CultureInfo = ss_CultureInfo;
    ss.initClass(ss_CultureInfo, ss, {
        getFormat: function CultureInfo$getFormat(type) {
            switch (type) {
                case ss_NumberFormatInfo: return this.numberFormat;
                case ss_DateTimeFormatInfo: return this.dateTimeFormat;
                default: return null;
            }
        }
    }, null, [ss_IFormatProvider]);

    ss_CultureInfo.invariantCulture = new ss_CultureInfo('en-US', ss_NumberFormatInfo.invariantInfo, ss_DateTimeFormatInfo.invariantInfo);
    ss_CultureInfo.currentCulture = ss_CultureInfo.invariantCulture;

    ///////////////////////////////////////////////////////////////////////////////
    // IEnumerator

    var ss_IEnumerator = function IEnumerator$() { };

    ss_IEnumerator.__typeName = 'ss.IEnumerator';
    ss.IEnumerator = ss_IEnumerator;
    ss.initInterface(ss_IEnumerator, ss, { current: null, moveNext: null, reset: null }, [ss_IDisposable]);

    ///////////////////////////////////////////////////////////////////////////////
    // IEnumerable

    var ss_IEnumerable = function IEnumerable$() { };

    ss_IEnumerable.__typeName = 'ss.IEnumerable';
    ss.IEnumerable = ss_IEnumerable;
    ss.initInterface(ss_IEnumerable, ss, { getEnumerator: null });
    ss.getEnumerator = function ss$getEnumerator(obj) {
        return obj.getEnumerator ? obj.getEnumerator() : new ss_ArrayEnumerator(obj);
    };

    ///////////////////////////////////////////////////////////////////////////////
    // ICollection

    var ss_ICollection = function ICollection$() { };

    ss_ICollection.__typeName = 'ss.ICollection';
    ss.ICollection = ss_ICollection;
    ss.initInterface(ss_ICollection, ss, { get_count: null, add: null, clear: null, contains: null, remove: null });

    ss.count = function ss$count(obj) {
        return obj.get_count ? obj.get_count() : obj.length;
    };

    ss.add = function ss$add(obj, item) {
        if (obj.add)
            obj.add(item);
        else if (ss.isArray(obj))
            obj.push(item);
        else
            throw new ss_NotSupportedException();
    };

    ss.clear = function ss$clear(obj) {
        if (obj.clear)
            obj.clear();
        else if (ss.isArray(obj))
            obj.length = 0;
        else
            throw new ss_NotSupportedException();
    };

    ss.remove = function ss$remove(obj, item) {
        if (obj.remove)
            return obj.remove(item);
        else if (ss.isArray(obj)) {
            var index = ss.indexOf(obj, item);
            if (index >= 0) {
                obj.splice(index, 1);
                return true;
            }
            return false;
        }
        else
            throw new ss_NotSupportedException();
    };

    ss.contains = function ss$contains(obj, item) {
        if (obj.contains)
            return obj.contains(item);
        else
            return ss.indexOf(obj, item) >= 0;
    };

    ///////////////////////////////////////////////////////////////////////////////
    // TimeSpan

    var ss_TimeSpan = function TimeSpan$(ticks) {
        this.ticks = ticks || 0;
    };

    ss_TimeSpan.getDefaultValue = ss_TimeSpan.createInstance = function TimeSpan$default() {
        return new ss_TimeSpan(0);
    };

    ss_TimeSpan.__typeName = 'ss.TimeSpan';
    ss.TimeSpan = ss_TimeSpan;
    ss.initClass(ss_TimeSpan, ss, {
        compareTo: function TimeSpan$compareTo(other) {
            return this.ticks < other.ticks ? -1 : (this.ticks > other.ticks ? 1 : 0);
        },
        equals: function TimeSpan$equals(other) {
            return ss.isInstanceOfType(other, ss_TimeSpan) && other.ticks === this.ticks;
        },
        equalsT: function TimeSpan$equalsT(other) {
            return other.ticks === this.ticks;
        },
        toString: function TimeSpan$toString() {
            var d = function (s, n) { return ss.padLeftString(s + '', n || 2, 48); };

            var ticks = this.ticks;
            var result = '';
            if (Math.abs(ticks) >= 864000000000) {
                result += d((ticks / 864000000000) | 0) + '.';
                ticks %= 864000000000;
            }
            result += d(ticks / 36000000000 | 0) + ':';
            ticks %= 36000000000;
            result += d(ticks / 600000000 | 0) + ':';
            ticks %= 600000000;
            result += d(ticks / 10000000 | 0);
            ticks %= 10000000;
            if (ticks > 0)
                result += '.' + d(ticks, 7);
            return result;
        }
    }, null, [ss_IComparable, ss_IEquatable]);
    ss_TimeSpan.__class = false;

    ///////////////////////////////////////////////////////////////////////////////
    // IEqualityComparer

    var ss_IEqualityComparer = function IEqualityComparer$() { };

    ss_IEqualityComparer.__typeName = 'ss.IEqualityComparer';
    ss.IEqualityComparer = ss_IEqualityComparer;
    ss.initInterface(ss_IEqualityComparer, ss, { areEqual: null, getObjectHashCode: null });

    ///////////////////////////////////////////////////////////////////////////////
    // IComparer

    var ss_IComparer = function IComparer$() { };

    ss_IComparer.__typeName = 'ss.IComparer';
    ss.IComparer = ss_IComparer;
    ss.initInterface(ss_IComparer, ss, { compare: null });

    ///////////////////////////////////////////////////////////////////////////////
    // Nullable

    ss.unbox = function ss$unbox(instance) {
        if (!ss.isValue(instance))
            throw new ss_InvalidOperationException('Nullable object must have a value.');
        return instance;
    };

    var ss_Nullable$1 = function Nullable$1$(T) {
        var $type = function () {
        };
        $type.isInstanceOfType = function (instance) {
            return ss.isInstanceOfType(instance, T);
        };
        ss.registerGenericClassInstance($type, ss_Nullable$1, [T], {}, function () { return null; }, function () { return []; });
        return $type;
    };

    ss_Nullable$1.__typeName = 'ss.Nullable$1';
    ss.Nullable$1 = ss_Nullable$1;
    ss.initGenericClass(ss_Nullable$1, ss, 1);

    ss_Nullable$1.eq = function Nullable$eq(a, b) {
        return !ss.isValue(a) ? !ss.isValue(b) : (a === b);
    };

    ss_Nullable$1.ne = function Nullable$eq(a, b) {
        return !ss.isValue(a) ? ss.isValue(b) : (a !== b);
    };

    ss_Nullable$1.le = function Nullable$le(a, b) {
        return ss.isValue(a) && ss.isValue(b) && a <= b;
    };

    ss_Nullable$1.ge = function Nullable$ge(a, b) {
        return ss.isValue(a) && ss.isValue(b) && a >= b;
    };

    ss_Nullable$1.lt = function Nullable$lt(a, b) {
        return ss.isValue(a) && ss.isValue(b) && a < b;
    };

    ss_Nullable$1.gt = function Nullable$gt(a, b) {
        return ss.isValue(a) && ss.isValue(b) && a > b;
    };

    ss_Nullable$1.sub = function Nullable$sub(a, b) {
        return ss.isValue(a) && ss.isValue(b) ? a - b : null;
    };

    ss_Nullable$1.add = function Nullable$add(a, b) {
        return ss.isValue(a) && ss.isValue(b) ? a + b : null;
    };

    ss_Nullable$1.mod = function Nullable$mod(a, b) {
        return ss.isValue(a) && ss.isValue(b) ? a % b : null;
    };

    ss_Nullable$1.div = function Nullable$divf(a, b) {
        return ss.isValue(a) && ss.isValue(b) ? a / b : null;
    };

    ss_Nullable$1.mul = function Nullable$mul(a, b) {
        return ss.isValue(a) && ss.isValue(b) ? a * b : null;
    };

    ss_Nullable$1.band = function Nullable$band(a, b) {
        return ss.isValue(a) && ss.isValue(b) ? a & b : null;
    };

    ss_Nullable$1.bor = function Nullable$bor(a, b) {
        return ss.isValue(a) && ss.isValue(b) ? a | b : null;
    };

    ss_Nullable$1.xor = function Nullable$xor(a, b) {
        return ss.isValue(a) && ss.isValue(b) ? a ^ b : null;
    };

    ss_Nullable$1.shl = function Nullable$shl(a, b) {
        return ss.isValue(a) && ss.isValue(b) ? a << b : null;
    };

    ss_Nullable$1.srs = function Nullable$srs(a, b) {
        return ss.isValue(a) && ss.isValue(b) ? a >> b : null;
    };

    ss_Nullable$1.sru = function Nullable$sru(a, b) {
        return ss.isValue(a) && ss.isValue(b) ? a >>> b : null;
    };

    ss_Nullable$1.and = function Nullable$and(a, b) {
        if (a === true && b === true)
            return true;
        else if (a === false || b === false)
            return false;
        else
            return null;
    };

    ss_Nullable$1.or = function Nullable$or(a, b) {
        if (a === true || b === true)
            return true;
        else if (a === false && b === false)
            return false;
        else
            return null;
    };

    ss_Nullable$1.not = function Nullable$not(a) {
        return ss.isValue(a) ? !a : null;
    };

    ss_Nullable$1.neg = function Nullable$neg(a) {
        return ss.isValue(a) ? -a : null;
    };

    ss_Nullable$1.pos = function Nullable$pos(a) {
        return ss.isValue(a) ? +a : null;
    };

    ss_Nullable$1.cpl = function Nullable$cpl(a) {
        return ss.isValue(a) ? ~a : null;
    };

    ss_Nullable$1.lift = function Nullable$lift() {
        for (var i = 0; i < arguments.length; i++) {
            if (!ss.isValue(arguments[i]))
                return null;
        }
        return arguments[0].apply(null, Array.prototype.slice.call(arguments, 1));
    };

    ///////////////////////////////////////////////////////////////////////////////
    // IList

    var ss_IList = function IList$() { };

    ss_IList.__typeName = 'ss.IList';
    ss.IList = ss_IList;
    ss.initInterface(ss_IList, ss, { get_item: null, set_item: null, indexOf: null, insert: null, removeAt: null }, [ss_ICollection, ss_IEnumerable]);

    ss.getItem = function ss$getItem(obj, index) {
        return obj.get_item ? obj.get_item(index) : obj[index];
    }

    ss.setItem = function ss$setItem(obj, index, value) {
        obj.set_item ? obj.set_item(index, value) : (obj[index] = value);
    }

    ss.indexOf = function ss$indexOf(obj, item) {
        if (ss.isArrayOrTypedArray(obj)) {
            for (var i = 0; i < obj.length; i++) {
                if (ss.staticEquals(obj[i], item)) {
                    return i;
                }
            }
            return -1;
        }
        else
            return obj.indexOf(item);
    };

    ss.insert = function ss$insert(obj, index, item) {
        if (obj.insert)
            obj.insert(index, item);
        else if (ss.isArray(obj))
            obj.splice(index, 0, item);
        else
            throw new ss_NotSupportedException();
    };

    ss.removeAt = function ss$removeAt(obj, index) {
        if (obj.removeAt)
            obj.removeAt(index);
        else if (ss.isArray(obj))
            obj.splice(index, 1);
        else
            throw new ss_NotSupportedException();
    };

    ///////////////////////////////////////////////////////////////////////////////
    // IDictionary

    var ss_IDictionary = function IDictionary$() { };

    ss_IDictionary.__typeName = 'ss.IDictionary';
    ss.IDictionary = ss_IDictionary;
    ss.initInterface(ss_IDictionary, ss, { get_item: null, set_item: null, get_keys: null, get_values: null, containsKey: null, add: null, remove: null, tryGetValue: null }, [ss_IEnumerable]);

    ///////////////////////////////////////////////////////////////////////////////
    // Int32

    var ss_Int32 = function Int32$() { };

    ss_Int32.__typeName = 'ss.Int32';
    ss.Int32 = ss_Int32;
    ss.initClass(ss_Int32, ss, {}, Object, [ss_IEquatable, ss_IComparable, ss_IFormattable]);
    ss_Int32.__class = false;

    ss_Int32.isInstanceOfType = function Int32$isInstanceOfType(instance) {
        return typeof (instance) === 'number' && isFinite(instance) && Math.round(instance, 0) == instance;
    };

    ss_Int32.getDefaultValue = ss_Int32.createInstance = function Int32$getDefaultValue() {
        return 0;
    };

    ss_Int32.div = function Int32$div(a, b) {
        if (!ss.isValue(a) || !ss.isValue(b)) return null;
        if (b === 0) throw new ss_DivideByZeroException();
        return a / b | 0;
    };

    ss_Int32.trunc = function Int32$trunc(n) {
        return ss.isValue(n) ? n | 0 : null;
    };

    ss_Int32.tryParse = function Int32$tryParse(s, result, min, max) {
        result.$ = 0;
        if (!/^[+-]?[0-9]+$/.test(s))
            return 0;
        var n = parseInt(s);
        if (n < min || n > max)
            return false;
        result.$ = n;
        return true;
    };

    ///////////////////////////////////////////////////////////////////////////////
    // MutableDateTime

    var ss_JsDate = function JsDate$() { };

    ss_JsDate.__typeName = 'ss.JsDate';
    ss.JsDate = ss_JsDate;
    ss.initClass(ss_JsDate, ss, {}, Object, [ss_IEquatable, ss_IComparable]);

    ss_JsDate.createInstance = function JsDate$createInstance() {
        return new Date();
    };

    ss_JsDate.isInstanceOfType = function JsDate$isInstanceOfType(instance) {
        return instance instanceof Date;
    };

    ///////////////////////////////////////////////////////////////////////////////
    // ArrayEnumerator

    var ss_ArrayEnumerator = function ArrayEnumerator$(array) {
        this._array = array;
        this._index = -1;
    };
    ss_ArrayEnumerator.__typeName = 'ss.ArrayEnumerator';
    ss.ArrayEnumerator = ss_ArrayEnumerator;
    ss.initClass(ss_ArrayEnumerator, ss, {
        moveNext: function ArrayEnumerator$moveNext() {
            this._index++;
            return (this._index < this._array.length);
        },
        reset: function ArrayEnumerator$reset() {
            this._index = -1;
        },
        current: function ArrayEnumerator$current() {
            if (this._index < 0 || this._index >= this._array.length)
                throw 'Invalid operation';
            return this._array[this._index];
        },
        dispose: function ArrayEnumerator$dispose() {
        }
    }, null, [ss_IEnumerator, ss_IDisposable]);

    ///////////////////////////////////////////////////////////////////////////////
    // ObjectEnumerator

    var ss_ObjectEnumerator = function ObjectEnumerator$(o) {
        this._keys = Object.keys(o);
        this._index = -1;
        this._object = o;
    };

    ss_ObjectEnumerator.__typeName = 'ss.ObjectEnumerator';
    ss.ObjectEnumerator = ss_ObjectEnumerator;
    ss.initClass(ss_ObjectEnumerator, ss, {
        moveNext: function ObjectEnumerator$moveNext() {
            this._index++;
            return (this._index < this._keys.length);
        },
        reset: function ObjectEnumerator$reset() {
            this._index = -1;
        },
        current: function ObjectEnumerator$current() {
            if (this._index < 0 || this._index >= this._keys.length)
                throw new ss_InvalidOperationException('Invalid operation');
            var k = this._keys[this._index];
            return { key: k, value: this._object[k] };
        },
        dispose: function ObjectEnumerator$dispose() {
        }
    }, null, [ss_IEnumerator, ss_IDisposable]);

    ///////////////////////////////////////////////////////////////////////////////
    // EqualityComparer

    var ss_EqualityComparer = function EqualityComparer$() {
    };
    ss_EqualityComparer.__typeName = 'ss.EqualityComparer';
    ss.EqualityComparer = ss_EqualityComparer;
    ss.initClass(ss_EqualityComparer, ss, {
        areEqual: function EqualityComparer$areEqual(x, y) {
            return ss.staticEquals(x, y);
        },
        getObjectHashCode: function EqualityComparer$getObjectHashCode(obj) {
            return ss.isValue(obj) ? ss.getHashCode(obj) : 0;
        }
    }, null, [ss_IEqualityComparer]);
    ss_EqualityComparer.def = new ss_EqualityComparer();

    ///////////////////////////////////////////////////////////////////////////////
    // Comparer

    var ss_Comparer = function Comparer$(f) {
        this.f = f;
    };

    ss_Comparer.__typeName = 'ss.Comparer';
    ss.Comparer = ss_Comparer;
    ss.initClass(ss_Comparer, ss, {
        compare: function Comparer$compare(x, y) {
            return this.f(x, y);
        }
    }, null, [ss_IComparer]);
    ss_Comparer.def = new ss_Comparer(function Comparer$defaultCompare(a, b) {
        if (!ss.isValue(a))
            return !ss.isValue(b) ? 0 : -1;
        else if (!ss.isValue(b))
            return 1;
        else
            return ss.compare(a, b);
    });

    ///////////////////////////////////////////////////////////////////////////////
    // Dictionary
    var ss_$DictionaryCollection = function $DictionaryCollection$(dict, isKeys) {
        this._dict = dict;
        this._isKeys = isKeys;
    };

    var ss_Dictionary$2 = function Dictionary$2$(TKey, TValue) {
        var $type = function (o, cmp) {
            this.countField = 0;
            this.buckets = {};

            this.comparer = cmp || ss_EqualityComparer.def;

            if (ss.isInstanceOfType(o, ss_IDictionary)) {
                var e = ss.getEnumerator(o);
                try {
                    while (e.moveNext()) {
                        var c = e.current();
                        this.add(c.key, c.value);
                    }
                }
                finally {
                    if (ss.isInstanceOfType(e, ss_IDisposable)) {
                        ss.cast(e, ss_IDisposable).dispose();
                    }
                }
            }
            else if (o) {
                var keys = Object.keys(o);
                for (var i = 0; i < keys.length; i++) {
                    this.add(keys[i], o[keys[i]]);
                }
            }
        };

        ss.registerGenericClassInstance($type, ss_Dictionary$2, [TKey, TValue], {
            _setOrAdd: function (key, value, add) {
                var hash = this.comparer.getObjectHashCode(key);
                var entry = { key: key, value: value };
                if (this.buckets.hasOwnProperty(hash)) {
                    var array = this.buckets[hash];
                    for (var i = 0; i < array.length; i++) {
                        if (this.comparer.areEqual(array[i].key, key)) {
                            if (add)
                                throw new ss_ArgumentException('Key ' + key + ' already exists.');
                            array[i] = entry;
                            return;
                        }
                    }
                    array.push(entry);
                } else {
                    this.buckets[hash] = [entry];
                }
                this.countField++;
            },

            add: function (key, value) {
                this._setOrAdd(key, value, true);
            },

            set_item: function (key, value) {
                this._setOrAdd(key, value, false);
            },

            _get: function (key) {
                var hash = this.comparer.getObjectHashCode(key);
                if (this.buckets.hasOwnProperty(hash)) {
                    var array = this.buckets[hash];
                    for (var i = 0; i < array.length; i++) {
                        var entry = array[i];
                        if (this.comparer.areEqual(entry.key, key))
                            return entry.value !== undefined ? entry.value : null;
                    }
                }
                return undefined;
            },

            get_item: function (key) {
                var v = this._get(key);
                if (v === undefined)
                    throw new ss_KeyNotFoundException('Key ' + key + ' does not exist.');
                return v;
            },

            tryGetValue: function (key, value) {
                var v = this._get(key);
                if (v !== undefined) {
                    value.$ = v;
                    return true;
                }
                else {
                    value.$ = ss.getDefaultValue(TValue);
                    return false;
                }
            },

            containsKey: function (key) {
                var hash = this.comparer.getObjectHashCode(key);
                if (!this.buckets.hasOwnProperty(hash))
                    return false;

                var array = this.buckets[hash];
                for (var i = 0; i < array.length; i++) {
                    if (this.comparer.areEqual(array[i].key, key))
                        return true;
                }
                return false;
            },

            clear: function () {
                this.countField = 0;
                this.buckets = {};
            },

            remove: function (key) {
                var hash = this.comparer.getObjectHashCode(key);
                if (!this.buckets.hasOwnProperty(hash))
                    return false;

                var array = this.buckets[hash];
                for (var i = 0; i < array.length; i++) {
                    if (this.comparer.areEqual(array[i].key, key)) {
                        array.splice(i, 1);
                        if (array.length == 0) delete this.buckets[hash];
                        this.countField--;
                        return true;
                    }
                }
                return false;
            },

            get_count: function () {
                return this.countField;
            },

            _getEnumerator: function (projector) {
                var bucketKeys = Object.keys(this.buckets), bucketIndex = -1, arrayIndex;
                return new ss_IteratorBlockEnumerator(function () {
                    if (bucketIndex < 0 || arrayIndex >= (this.buckets[bucketKeys[bucketIndex]].length - 1)) {
                        arrayIndex = -1;
                        bucketIndex++;
                    }
                    if (bucketIndex >= bucketKeys.length)
                        return false;
                    arrayIndex++;
                    return true;
                }, function () { return projector(this.buckets[bucketKeys[bucketIndex]][arrayIndex]); }, null, this);
            },

            get_keys: function () {
                return new ss_$DictionaryCollection(this, true);
            },

            get_values: function () {
                return new ss_$DictionaryCollection(this, false);
            },

            getEnumerator: function () {
                return this._getEnumerator(function (e) { return e; });
            }
        }, function () { return null; }, function () { return [ss_IDictionary, ss_IEnumerable]; });
        return $type;
    };

    ss_Dictionary$2.__typeName = 'ss.Dictionary$2';
    ss.Dictionary$2 = ss_Dictionary$2;
    ss.initGenericClass(ss_Dictionary$2, ss, 2);
    ss_$DictionaryCollection.__typeName = 'ss.$DictionaryCollection';
    ss.$DictionaryCollection = ss_$DictionaryCollection;
    ss.initClass(ss_$DictionaryCollection, ss, {
        get_count: function $DictionaryCollection$get_count() {
            return this._dict.get_count();
        },
        contains: function $DictionaryCollection$contains(v) {
            if (this._isKeys) {
                return this._dict.containsKey(v);
            }
            else {
                for (var e in this._dict.buckets) {
                    if (this._dict.buckets.hasOwnProperty(e)) {
                        var bucket = this._dict.buckets[e];
                        for (var i = 0; i < bucket.length; i++) {
                            if (this._dict.comparer.areEqual(bucket[i].value, v))
                                return true;
                        }
                    }
                }
                return false;
            }
        },
        getEnumerator: function $DictionaryCollection$getEnumerator(v) {
            return this._dict._getEnumerator(this._isKeys ? function (e) { return e.key; } : function (e) { return e.value; });
        },
        add: function $DictionaryCollection$add(v) {
            throw new ss_InvalidOperationException('Collection is read-only');
        },
        clear: function $DictionaryCollection$clear() {
            throw new ss_InvalidOperationException('Collection is read-only');
        },
        remove: function $DictionaryCollection$remove() {
            throw new ss_InvalidOperationException('Collection is read-only');
        }
    }, null, [ss_IEnumerable, ss_ICollection]);

    ///////////////////////////////////////////////////////////////////////////////
    // IDisposable

    var ss_IDisposable = function IDisposable$() { };
    ss_IDisposable.__typeName = 'ss.IDisposable';
    ss.IDisposable = ss_IDisposable;
    ss.initInterface(ss_IDisposable, ss, { dispose: null });

    ///////////////////////////////////////////////////////////////////////////////
    // StringBuilder

    var ss_StringBuilder = function StringBuilder$(s) {
        this._parts = (ss.isValue(s) && s != '') ? [s] : [];
        this.length = ss.isValue(s) ? s.length : 0;
    }

    ss_StringBuilder.__typeName = 'ss.StringBuilder';
    ss.StringBuilder = ss_StringBuilder;
    ss.initClass(ss_StringBuilder, ss, {
        append: function StringBuilder$append(o) {
            if (ss.isValue(o)) {
                var s = o.toString();
                ss.add(this._parts, s);
                this.length += s.length;
            }
            return this;
        },

        appendChar: function StringBuilder$appendChar(c) {
            return this.append(String.fromCharCode(c));
        },

        appendLine: function StringBuilder$appendLine(s) {
            this.append(s);
            this.append('\r\n');
            return this;
        },

        appendLineChar: function StringBuilder$appendLineChar(c) {
            return this.appendLine(String.fromCharCode(c));
        },

        clear: function StringBuilder$clear() {
            this._parts = [];
            this.length = 0;
        },

        toString: function StringBuilder$toString() {
            return this._parts.join('');
        }
    });

    ///////////////////////////////////////////////////////////////////////////////
    // Random

    var ss_Random = function Random$(seed) {
        var _seed = (seed === undefined) ? parseInt(Date.now() % 2147483648) : parseInt(Math.abs(seed));
        this.inext = 0;
        this.inextp = 21;
        this.seedArray = new Array(56);
        for (var i = 0; i < 56; i++)
            this.seedArray[i] = 0;

        _seed = 161803398 - _seed;
        if (_seed < 0)
            _seed += 2147483648;
        this.seedArray[55] = _seed;
        var mk = 1;
        for (var i = 1; i < 55; i++) {
            var ii = (21 * i) % 55;
            this.seedArray[ii] = mk;
            mk = _seed - mk;
            if (mk < 0)
                mk += 2147483648;

            _seed = this.seedArray[ii];
        }
        for (var j = 1; j < 5; j++) {
            for (var k = 1; k < 56; k++) {
                this.seedArray[k] -= this.seedArray[1 + (k + 30) % 55];
                if (this.seedArray[k] < 0)
                    this.seedArray[k] += 2147483648;
            }
        }
    };

    ss_Random.__typeName = 'ss.Random';
    ss.Random = ss_Random;
    ss.initClass(ss_Random, ss, {
        next: function Random$next() {
            return this.sample() * 2147483648 | 0;
        },
        nextMax: function Random$nextMax(max) {
            return this.sample() * max | 0;
        },
        nextMinMax: function Random$nextMinMax(min, max) {
            return (this.sample() * (max - min) + min) | 0;
        },
        nextBytes: function Random$nextBytes(bytes) {
            for (var i = 0; i < bytes.length; i++)
                bytes[i] = (this.sample() * 256) | 0;
        },
        nextDouble: function Random$nextDouble() {
            return this.sample();
        },
        sample: function Random$sample() {
            if (++this.inext >= 56)
                this.inext = 1;
            if (++this.inextp >= 56)
                this.inextp = 1;

            var retVal = this.seedArray[this.inext] - this.seedArray[this.inextp];

            if (retVal < 0)
                retVal += 2147483648;

            this.seedArray[this.inext] = retVal;

            return retVal * (1.0 / 2147483648);
        }
    });

    ///////////////////////////////////////////////////////////////////////////////
    // EventArgs

    var ss_EventArgs = function EventArgs$() {
    }
    ss_EventArgs.__typeName = 'ss.EventArgs';
    ss.EventArgs = ss_EventArgs;
    ss.initClass(ss_EventArgs, ss, {});

    ss_EventArgs.Empty = new ss_EventArgs();

    ///////////////////////////////////////////////////////////////////////////////
    // Exception

    var ss_Exception = function Exception$(message, innerException) {
        this._message = message || 'An error occurred.';
        this._innerException = innerException || null;
    }

    ss_Exception.__typeName = 'ss.Exception';
    ss.Exception = ss_Exception;
    ss.initClass(ss_Exception, ss, {
        get_message: function Exception$get_message() {
            return this._message;
        },
        get_innerException: function Exception$get_innerException() {
            return this._innerException;
        }
    });

    ss_Exception.wrap = function Exception$wrap(o) {
        if (ss.isInstanceOfType(o, ss_Exception)) {
            return o;
        }
        else if (o instanceof TypeError) {
            // TypeError can either be 'cannot read property blah of null/undefined' (proper NullReferenceException), or it can be eg. accessing a non-existent method of an object.
            // As long as all code is compiled, they should with a very high probability indicate the use of a null reference.
            return new ss_NullReferenceException(o.message);
        }
        else if (o instanceof RangeError) {
            return new ss_ArgumentOutOfRangeException(null, o.message);
        }
        else if (o instanceof Error) {
            return new ss_JsErrorException(o);
        }
        else {
            return new ss_Exception(o.toString());
        }
    };

    ////////////////////////////////////////////////////////////////////////////////
    // NotImplementedException

    var ss_NotImplementedException = function NotImplementedException$(message, innerException) {
        ss_Exception.call(this, message || 'The method or operation is not implemented.', innerException);
    };
    ss_NotImplementedException.__typeName = 'ss.NotImplementedException';
    ss.NotImplementedException = ss_NotImplementedException;
    ss.initClass(ss_NotImplementedException, ss, {}, ss_Exception);

    ////////////////////////////////////////////////////////////////////////////////
    // NotSupportedException

    var ss_NotSupportedException = function NotSupportedException$(message, innerException) {
        ss_Exception.call(this, message || 'Specified method is not supported.', innerException);
    };
    ss_NotSupportedException.__typeName = 'ss.NotSupportedException';
    ss.NotSupportedException = ss_NotSupportedException;
    ss.initClass(ss_NotSupportedException, ss, {}, ss_Exception);

    ////////////////////////////////////////////////////////////////////////////////
    // AggregateException

    var ss_AggregateException = function AggregateException$(message, innerExceptions) {
        this.innerExceptions = ss.isValue(innerExceptions) ? ss.arrayFromEnumerable(innerExceptions) : [];
        ss_Exception.call(this, message || 'One or more errors occurred.', this.innerExceptions.length ? this.innerExceptions[0] : null);
    };

    ss_AggregateException.__typeName = 'ss.AggregateException';
    ss.AggregateException = ss_AggregateException;
    ss.initClass(ss_AggregateException, ss, {
        flatten: function AggregateException$flatten() {
            var inner = [];
            for (var i = 0; i < this.innerExceptions.length; i++) {
                var e = this.innerExceptions[i];
                if (ss.isInstanceOfType(e, ss_AggregateException)) {
                    inner.push.apply(inner, e.flatten().innerExceptions);
                }
                else {
                    inner.push(e);
                }
            }
            return new ss_AggregateException(this._message, inner);
        }
    }, ss_Exception);

    ////////////////////////////////////////////////////////////////////////////////
    // PromiseException

    var ss_PromiseException = function PromiseException(args, message, innerException) {
        ss_Exception.call(this, message || (args.length && args[0] ? args[0].toString() : 'An error occurred'), innerException);
        this.arguments = ss.arrayClone(args);
    };

    ss_PromiseException.__typeName = 'ss.PromiseException';
    ss.PromiseException = ss_PromiseException;
    ss.initClass(ss_PromiseException, ss, {
        get_arguments: function PromiseException$get_arguments() {
            return this._arguments;
        }
    }, ss_Exception);

    ////////////////////////////////////////////////////////////////////////////////
    // JsErrorException

    var ss_JsErrorException = function JsErrorException$(error, message, innerException) {
        ss_Exception.call(this, message || error.message, innerException);
        this.error = error;
    };
    ss_JsErrorException.__typeName = 'ss.JsErrorException';
    ss.JsErrorException = ss_JsErrorException;
    ss.initClass(ss_JsErrorException, ss, {}, ss_Exception);

    ////////////////////////////////////////////////////////////////////////////////
    // ArgumentException

    var ss_ArgumentException = function ArgumentException$(message, paramName, innerException) {
        ss_Exception.call(this, message || 'Value does not fall within the expected range.', innerException);
        this.paramName = paramName || null;
    };

    ss_ArgumentException.__typeName = 'ss.ArgumentException';
    ss.ArgumentException = ss_ArgumentException;
    ss.initClass(ss_ArgumentException, ss, {}, ss_Exception);

    ////////////////////////////////////////////////////////////////////////////////
    // ArgumentNullException

    var ss_ArgumentNullException = function ArgumentNullException$(paramName, message, innerException) {
        if (!message) {
            message = 'Value cannot be null.';
            if (paramName)
                message += '\nParameter name: ' + paramName;
        }

        ss_ArgumentException.call(this, message, paramName, innerException);
    };

    ss_ArgumentNullException.__typeName = 'ss.ArgumentNullException';
    ss.ArgumentNullException = ss_ArgumentNullException;
    ss.initClass(ss_ArgumentNullException, ss, {}, ss_ArgumentException);

    ////////////////////////////////////////////////////////////////////////////////
    // ArgumentNullException

    var ss_ArgumentOutOfRangeException = function ArgumentOutOfRangeException$(paramName, message, innerException, actualValue) {
        if (!message) {
            message = 'Value is out of range.';
            if (paramName)
                message += '\nParameter name: ' + paramName;
        }

        ss_ArgumentException.call(this, message, paramName, innerException);
        this.actualValue = actualValue || null;
    };

    ss_ArgumentOutOfRangeException.__typeName = 'ss.ArgumentOutOfRangeException';
    ss.ArgumentOutOfRangeException = ss_ArgumentOutOfRangeException;
    ss.initClass(ss_ArgumentOutOfRangeException, ss, {}, ss_ArgumentException);

    ////////////////////////////////////////////////////////////////////////////////
    // FormatException

    var ss_FormatException = function FormatException$(message, innerException) {
        ss_Exception.call(this, message || 'Invalid format.', innerException);
    };
    ss_FormatException.__typeName = 'ss.FormatException';
    ss.FormatException = ss_FormatException;
    ss.initClass(ss_FormatException, ss, {}, ss_Exception);

    ////////////////////////////////////////////////////////////////////////////////
    // DivideByZeroException

    var ss_DivideByZeroException = function DivideByZeroException$(message, innerException) {
        ss_Exception.call(this, message || 'Division by 0.', innerException);
    };
    ss_DivideByZeroException.__typeName = 'ss.DivideByZeroException';
    ss.DivideByZeroException = ss_DivideByZeroException;
    ss.initClass(ss_DivideByZeroException, ss, {}, ss_Exception);

    ////////////////////////////////////////////////////////////////////////////////
    // InvalidCastException

    var ss_InvalidCastException = function InvalidCastException$(message, innerException) {
        ss_Exception.call(this, message || 'The cast is not valid.', innerException);
    };
    ss_InvalidCastException.__typeName = 'ss.InvalidCastException';
    ss.InvalidCastException = ss_InvalidCastException;
    ss.initClass(ss_InvalidCastException, ss, {}, ss_Exception);

    ////////////////////////////////////////////////////////////////////////////////
    // InvalidOperationException

    var ss_InvalidOperationException = function InvalidOperationException$(message, innerException) {
        ss_Exception.call(this, message || 'Operation is not valid due to the current state of the object.', innerException);
    };
    ss_InvalidOperationException.__typeName = 'ss.InvalidOperationException';
    ss.InvalidOperationException = ss_InvalidOperationException;
    ss.initClass(ss_InvalidOperationException, ss, {}, ss_Exception);

    ////////////////////////////////////////////////////////////////////////////////
    // NullReferenceException

    var ss_NullReferenceException = function NullReferenceException$(message, innerException) {
        ss_Exception.call(this, message || 'Object is null.', innerException);
    };
    ss_NullReferenceException.__typeName = 'ss.NullReferenceException';
    ss.NullReferenceException = ss_NullReferenceException;
    ss.initClass(ss_NullReferenceException, ss, {}, ss_Exception);

    ////////////////////////////////////////////////////////////////////////////////
    // KeyNotFoundException

    var ss_KeyNotFoundException = function KeyNotFoundException$(message, innerException) {
        ss_Exception.call(this, message || 'Key not found.', innerException);
    };
    ss_KeyNotFoundException.__typeName = 'ss.KeyNotFoundException';
    ss.KeyNotFoundException = ss_KeyNotFoundException;
    ss.initClass(ss_KeyNotFoundException, ss, {}, ss_Exception);

    ////////////////////////////////////////////////////////////////////////////////
    // InvalidOperationException

    var ss_AmbiguousMatchException = function AmbiguousMatchException$(message, innerException) {
        ss_Exception.call(this, message || 'Ambiguous match.', innerException);
    };
    ss_AmbiguousMatchException.__typeName = 'ss.AmbiguousMatchException';
    ss.AmbiguousMatchException = ss_AmbiguousMatchException;
    ss.initClass(ss_AmbiguousMatchException, ss, {}, ss_Exception);

    ///////////////////////////////////////////////////////////////////////////////
    // IteratorBlockEnumerable

    var ss_IteratorBlockEnumerable = function IteratorBlockEnumerable$(getEnumerator, $this) {
        this._getEnumerator = getEnumerator;
        this._this = $this;
    };

    ss_IteratorBlockEnumerable.__typeName = 'ss.IteratorBlockEnumerable';
    ss.IteratorBlockEnumerable = ss_IteratorBlockEnumerable;
    ss.initClass(ss_IteratorBlockEnumerable, ss, {
        getEnumerator: function IteratorBlockEnumerable$getEnumerator() {
            return this._getEnumerator.call(this._this);
        }
    }, null, [ss_IEnumerable]);

    ///////////////////////////////////////////////////////////////////////////////
    // IteratorBlockEnumerator

    var ss_IteratorBlockEnumerator = function IteratorBlockEnumerator$(moveNext, getCurrent, dispose, $this) {
        this._moveNext = moveNext;
        this._getCurrent = getCurrent;
        this._dispose = dispose;
        this._this = $this;
    };

    ss_IteratorBlockEnumerator.__typeName = 'ss.IteratorBlockEnumerator';
    ss.IteratorBlockEnumerator = ss_IteratorBlockEnumerator;
    ss.initClass(ss_IteratorBlockEnumerator, ss, {
        moveNext: function IteratorBlockEnumerator$moveNext() {
            try {
                return this._moveNext.call(this._this);
            }
            catch (ex) {
                if (this._dispose)
                    this._dispose.call(this._this);
                throw ex;
            }
        },
        current: function IteratorBlockEnumerator$current() {
            return this._getCurrent.call(this._this);
        },
        reset: function IteratorBlockEnumerator$reset() {
            throw new ss_NotSupportedException('Reset is not supported.');
        },
        dispose: function IteratorBlockEnumerator$dispose() {
            if (this._dispose)
                this._dispose.call(this._this);
        }
    }, null, [ss_IEnumerator, ss_IDisposable]);

    ///////////////////////////////////////////////////////////////////////////////
    // Lazy

    var ss_Lazy = function Lazy$(valueFactory) {
        this._valueFactory = valueFactory;
        this.isValueCreated = false;
    };
    ss_Lazy.__typeName = 'ss.Lazy';
    ss.Lazy = ss_Lazy;
    ss.initClass(ss_Lazy, ss, {
        value: function Lazy$value() {
            if (!this.isValueCreated) {
                this._value = this._valueFactory();
                delete this._valueFactory;
                this.isValueCreated = true;
            }
            return this._value;
        }
    });

    ///////////////////////////////////////////////////////////////////////////////
    // Task

    var ss_Task = function Task$(action, state) {
        this._action = action;
        this._state = state;
        this.exception = null;
        this.status = 0;
        this._thens = [];
        this._result = null;
    };

    ss_Task.delay = function Task$delay(delay) {
        var tcs = new ss_TaskCompletionSource();
        setTimeout(function () {
            tcs.setResult(0);
        }, delay);
        return tcs.task;
    };

    ss_Task.fromResult = function Task$fromResult(result) {
        var t = new ss_Task();
        t.status = 5;
        t._result = result;
        return t;
    };

    ss_Task.run = function Task$fromResult(f) {
        var tcs = new ss_TaskCompletionSource();
        setTimeout(function () {
            try {
                tcs.setResult(f());
            }
            catch (e) {
                tcs.setException(ss_Exception.wrap(e));
            }
        }, 0);
        return tcs.task;
    };

    ss_Task.whenAll = function Task$whenAll(tasks) {
        var tcs = new ss_TaskCompletionSource();
        if (tasks.length === 0) {
            tcs.setResult([]);
        }
        else {
            var result = new Array(tasks.length), remaining = tasks.length, cancelled = false, exceptions = [];
            for (var i = 0; i < tasks.length; i++) {
                (function (i) {
                    tasks[i].continueWith(function (t) {
                        switch (t.status) {
                            case 5:
                                result[i] = t.getResult();
                                break;
                            case 6:
                                cancelled = true;
                                break;
                            case 7:
                                ss.arrayAddRange(exceptions, t.exception.innerExceptions);
                                break;
                            default:
                                throw new ss_InvalidOperationException('Invalid task status ' + t.status);
                        }
                        if (--remaining === 0) {
                            if (exceptions.length > 0)
                                tcs.setException(exceptions);
                            else if (cancelled)
                                tcs.setCanceled();
                            else
                                tcs.setResult(result);
                        }
                    });
                })(i);
            }
        }
        return tcs.task;
    };

    ss_Task.whenAny = function Task$whenAny(tasks) {
        if (!tasks.length)
            throw new ss_ArgumentException('Must wait for at least one task', 'tasks');

        var tcs = new ss_TaskCompletionSource();
        for (var i = 0; i < tasks.length; i++) {
            tasks[i].continueWith(function (t) {
                switch (t.status) {
                    case 5:
                        tcs.trySetResult(t);
                        break;
                    case 6:
                        tcs.trySetCanceled();
                        break;
                    case 7:
                        tcs.trySetException(t.exception.innerExceptions);
                        break;
                    default:
                        throw new ss_InvalidOperationException('Invalid task status ' + t.status);
                }
            });
        }
        return tcs.task;
    };

    ss_Task.fromDoneCallback = function Task$fromDoneCallback(t, i, m) {
        var tcs = new ss_TaskCompletionSource(), args;
        if (typeof (i) === 'number') {
            args = Array.prototype.slice.call(arguments, 3);
            if (i < 0)
                i += args.length + 1;
        }
        else {
            args = Array.prototype.slice.call(arguments, 2);
            m = i;
            i = args.length;
        }

        var cb = function (v) {
            tcs.setResult(v);
        };

        args = args.slice(0, i).concat(cb, args.slice(i));

        t[m].apply(t, args);
        return tcs.task;
    };

    ss_Task.fromPromise = function Task$fromPromise(p, f) {
        var tcs = new ss_TaskCompletionSource();
        if (typeof (f) === 'number')
            f = (function (i) { return function () { return arguments[i >= 0 ? i : (arguments.length + i)]; }; })(f);
        else if (typeof (f) !== 'function')
            f = function () { return Array.prototype.slice.call(arguments, 0); };

        p.then(function () {
            tcs.setResult(typeof (f) === 'function' ? f.apply(null, arguments) : null);
        }, function () {
            tcs.setException(new ss_PromiseException(Array.prototype.slice.call(arguments, 0)));
        });
        return tcs.task;
    };

    ss_Task.fromNode = function Task$fromNode(t, f, m) {
        var tcs = new ss_TaskCompletionSource(), args;
        if (typeof (f) === 'function') {
            args = Array.prototype.slice.call(arguments, 3);
        }
        else {
            args = Array.prototype.slice.call(arguments, 2);
            m = f;
            f = function () { return arguments[0]; };
        }

        var cb = function (e) {
            if (e)
                tcs.setException(ss_Exception.wrap(e));
            else
                tcs.setResult(f.apply(null, Array.prototype.slice.call(arguments, 1)));
        };

        args.push(cb);

        t[m].apply(t, args);
        return tcs.task;
    };

    ss_Task.__typeName = 'ss.Task';
    ss.Task = ss_Task;
    ss.initClass(ss_Task, ss, {
        continueWith: function Task$continueWith(continuation) {
            var tcs = new ss_TaskCompletionSource();
            var _this = this;
            var fn = function () {
                try {
                    tcs.setResult(continuation(_this));
                }
                catch (e) {
                    tcs.setException(ss_Exception.wrap(e));
                }
            };
            if (this.isCompleted()) {
                setTimeout(fn, 0);
            }
            else {
                this._thens.push(fn);
            }
            return tcs.task;
        },
        start: function Task$start() {
            if (this.status !== 0)
                throw new ss_InvalidOperationException('Task was already started.');
            var _this = this;
            this.status = 3;
            setTimeout(function () {
                try {
                    var result = _this._action(_this._state);
                    delete _this._action;
                    delete _this._state;
                    _this._complete(result);
                }
                catch (e) {
                    _this._fail(new ss_AggregateException(null, [ss_Exception.wrap(e)]));
                }
            }, 0);
        },
        _runCallbacks: function Task$_runCallbacks() {
            for (var i = 0; i < this._thens.length; i++)
                this._thens[i](this);
            delete this._thens;
        },
        _complete: function Task$_complete(result) {
            if (this.isCompleted())
                return false;
            this._result = result;
            this.status = 5;
            this._runCallbacks();
            return true;
        },
        _fail: function Task$_fail(exception) {
            if (this.isCompleted())
                return false;
            this.exception = exception;
            this.status = 7;
            this._runCallbacks();
            return true;
        },
        _cancel: function Task$_cancel() {
            if (this.isCompleted())
                return false;
            this.status = 6;
            this._runCallbacks();
            return true;
        },
        isCanceled: function Task$isCanceled() {
            return this.status === 6;
        },
        isCompleted: function Task$isCompleted() {
            return this.status >= 5;
        },
        isFaulted: function Task$isFaulted() {
            return this.status === 7;
        },
        _getResult: function Task$_getResult(await) {
            switch (this.status) {
                case 5:
                    return this._result;
                case 6:
                    throw new ss_InvalidOperationException('Task was cancelled.');
                case 7:
                    throw await ? this.exception.innerExceptions[0] : this.exception;
                default:
                    throw new ss_InvalidOperationException('Task is not yet completed.');
            }
        },
        getResult: function Task$getResult() {
            return this._getResult(false);
        },
        getAwaitedResult: function Task$getAwaitedResult() {
            return this._getResult(true);
        },
        dispose: function Task$dispose() {
        }
    }, null, [ss_IDisposable]);

    ////////////////////////////////////////////////////////////////////////////////
    // TaskStatus
    var ss_TaskStatus = function () {
    };
    ss_TaskStatus.__typeName = 'ss.TaskStatus';
    ss.TaskStatus = ss_TaskStatus;
    ss.initEnum(ss_TaskStatus, ss, { created: 0, running: 3, ranToCompletion: 5, canceled: 6, faulted: 7 });

    ///////////////////////////////////////////////////////////////////////////////
    // TaskCompletionSource

    var ss_TaskCompletionSource = function TaskCompletionSource$() {
        this.task = new ss_Task();
        this.task.status = 3;
    };

    ss_TaskCompletionSource.__typeName = 'ss.TaskCompletionSource';
    ss.TaskCompletionSource = ss_TaskCompletionSource;
    ss.initClass(ss_TaskCompletionSource, ss, {
        setCanceled: function TaskCompletionSource$setCanceled() {
            if (!this.task._cancel())
                throw new ss_InvalidOperationException('Task was already completed.');
        },
        setResult: function TaskCompletionSource$setResult(result) {
            if (!this.task._complete(result))
                throw new ss_InvalidOperationException('Task was already completed.');
        },
        setException: function TaskCompletionSource$setException(exception) {
            if (!this.trySetException(exception))
                throw new ss_InvalidOperationException('Task was already completed.');
        },
        trySetCanceled: function TaskCompletionSource$trySetCanceled() {
            return this.task._cancel();
        },
        trySetResult: function TaskCompletionSource$setResult(result) {
            return this.task._complete(result);
        },
        trySetException: function TaskCompletionSource$setException(exception) {
            if (ss.isInstanceOfType(exception, ss_Exception))
                exception = [exception];
            return this.task._fail(new ss_AggregateException(null, exception));
        }
    });

    ///////////////////////////////////////////////////////////////////////////////
    // CancelEventArgs

    var ss_CancelEventArgs = function CancelEventArgs$() {
        ss_EventArgs.call(this);
        this.cancel = false;
    }

    ss_CancelEventArgs.__typeName = 'ss.CancelEventArgs';
    ss.CancelEventArgs = ss_CancelEventArgs;
    ss.initClass(ss_CancelEventArgs, ss, {}, ss_EventArgs);

    ///////////////////////////////////////////////////////////////////////////////
    // Guid

    var ss_Guid = function Guid$() {
    };
    ss_Guid.$valid = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/ig;
    ss_Guid.$split = /^(.{8})(.{4})(.{4})(.{4})(.{12})$/;
    ss_Guid.empty = '00000000-0000-0000-0000-000000000000';
    ss_Guid.$rng = new ss_Random();

    ss_Guid.__typeName = 'ss.Guid';
    ss.Guid = ss_Guid;
    ss.initClass(ss_Guid, ss, {}, Object, [ss_IEquatable, ss_IComparable]);
    ss_Guid.__class = false;

    ss_Guid.isInstanceOfType = function Guid$isInstanceOfType(instance) {
        return typeof (instance) === 'string' && instance.match(ss_Guid.$valid);
    };

    ss_Guid.getDefaultValue = ss_Guid.createInstance = function Guid$default() {
        return ss_Guid.empty;
    };

    ss_Guid.parse = function Guid$parse(uuid, format) {
        var r = {};
        if (ss_Guid.tryParse(uuid, format, r))
            return r.$;
        throw new ss_FormatException('Unable to parse UUID');
    };

    ss_Guid.tryParse = function Guid$tryParse(uuid, format, r) {
        r.$ = ss_Guid.empty;
        if (!ss.isValue(uuid)) throw new ss_ArgumentNullException('uuid');
        if (!format) {
            var m = /^[{(]?([0-9a-f]{8})-?([0-9a-f]{4})-?([0-9a-f]{4})-?([0-9a-f]{4})-?([0-9a-f]{12})[)}]?$/ig.exec(uuid);
            if (m) {
                r.$ = m.slice(1).join('-').toLowerCase();
                return true;
            }
        }
        else {
            if (format === 'N') {
                var m = ss_Guid.$split.exec(uuid);
                if (!m)
                    return false;
                uuid = m.slice(1).join('-');
            }
            else if (format === 'B' || format === 'P') {
                var b = format === 'B';
                if (uuid[0] !== (b ? '{' : '(') || uuid[uuid.length - 1] !== (b ? '}' : ')'))
                    return false;
                uuid = uuid.substr(1, uuid.length - 2);
            }
            if (uuid.match(ss_Guid.$valid)) {
                r.$ = uuid.toLowerCase();
                return true;
            }
        }
        return false;
    };

    ss_Guid.format = function Guid$format(uuid, format) {
        switch (format) {
            case 'N': return uuid.replace(/-/g, '');
            case 'B': return '{' + uuid + '}';
            case 'P': return '(' + uuid + ')';
            default: return uuid;
        }
    }

    ss_Guid.fromBytes = function Guid$fromBytes(b) {
        if (!b || b.length !== 16)
            throw new ss_ArgumentException('b', 'Must be 16 bytes');
        var s = b.map(function (x) { return ss.formatNumber(x & 0xff, 'x2'); }).join('');
        return ss_Guid.$split.exec(s).slice(1).join('-');
    }

    ss_Guid.newGuid = function Guid$newGuid() {
        var a = Array(16);
        ss_Guid.$rng.nextBytes(a);
        a[6] = a[6] & 0x0f | 0x40;
        a[8] = a[8] & 0xbf | 0x80;
        return ss_Guid.fromBytes(a);
    };

    ss_Guid.getBytes = function Guid$getBytes(uuid) {
        var a = Array(16);
        var s = uuid.replace(/-/g, '');
        for (var i = 0; i < 16; i++) {
            a[i] = parseInt(s.substr(i * 2, 2), 16);
        }
        return a;
    };

    if (global.ss) {
        for (var n in ss) {
            if (ss.hasOwnProperty(n))
                global.ss[n] = ss[n];
        }
    }
    else {
        global.ss = ss;
    }
})(global);
